diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..96fa2db9b --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: jankotek diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..5c9fb507e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +--- +name: Java CI + +on: [push] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-18.04, macOS-latest, windows-2016] + java: [8, 11] + fail-fast: false + max-parallel: 4 + name: Test JDK ${{ matrix.java }}, ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Test with Gradle + run: ./gradlew test +... \ No newline at end of file diff --git a/.gitignore b/.gitignore index 56a24e63a..d669ddbd7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,17 @@ .settings .idea target +build bin out helper *.iml *.ipr -*.iws \ No newline at end of file +*.iws +.directory +*.log +.gradle +*.log + + +srcGen/* \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 546a954c0..76f870814 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,28 @@ language: java -cache: - directories: - - $HOME/.m2 jdk: - - oraclejdk7 - - openjdk7 - - openjdk6 + - openjdk8 + - openjdk11 +# - oraclejdk10 + +sudo: false + +before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + +#before_install: +# - sudo apt-get purge gradle +# - sudo add-apt-repository ppa:cwchien/gradle -y +# - sudo apt-get update -q +# - sudo apt-get install gradle -y + +cache: + directories: + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ + - $HOME/.m2/repository/ -install: true +install: /bin/true -script: mvn test +script: ./gradlew test diff --git a/license.txt b/LICENSE.txt similarity index 100% rename from license.txt rename to LICENSE.txt diff --git a/README.md b/README.md index 5b4189ba5..972b13432 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,64 @@ -MapDB provides concurrent Maps, Sets and Queues backed by disk storage or off-heap memory. -MapDB is free as speech and free as beer under -[Apache License 2.0](https://github.com/jankotek/MapDB/blob/master/doc/license.txt). + -Find out more at: - * [Home page - www.mapdb.org](http://www.mapdb.org) - * [Introduction](http://www.mapdb.org/02-getting-started.html) - * [Examples](https://github.com/jankotek/MapDB/tree/master/src/test/java/examples) - * [Javadoc](http://www.mapdb.org/apidocs/index.html) +MapDB: database engine +======================= +[![Build Status](https://travis-ci.org/jankotek/mapdb.svg?branch=master)](https://travis-ci.org/jankotek/mapdb) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.mapdb/mapdb/badge.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.mapdb%22%20AND%20a%3Amapdb) +[![Join the chat at https://gitter.im/jankotek/mapdb](https://badges.gitter.im/jankotek/mapdb.svg)](https://gitter.im/jankotek/mapdb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -15 minutes overview +MapDB combines embedded database engine and Java collections. +It is free under Apache 2 license. MapDB is flexible and can be used in many roles: + +* Drop-in replacement for Maps, Lists, Queues and other collections. +* Off-heap collections not affected by Garbage Collector +* Multilevel cache with expiration and disk overflow. +* RDBMs replacement with transactions, MVCC, incremental backups etc… +* Local data processing and filtering. MapDB has utilities to process huge quantities of data in reasonable time. + +Hello world +------------------- + +Maven snippet, VERSION is [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.mapdb/mapdb/badge.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.mapdb%22%20AND%20a%3Amapdb) + +```xml + + org.mapdb + mapdb + VERSION + +``` + +Hello world: + +```java +//import org.mapdb.* +DB db = DBMaker.memoryDB().make(); +ConcurrentMap map = db.hashMap("map").make(); +map.put("something", "here"); +``` + +You can continue with [quick start](https://jankotek.gitbooks.io/mapdb/content/quick-start/) or refer to the [documentation](https://jankotek.gitbooks.io/mapdb/). + +Support ------------ - +More [details](http://www.mapdb.org/support/). + +Development +-------------------- +MapDB is written in Kotlin, you will need IntelliJ Idea. +You can use Gradle to build MapDB. +MapDB is extensively unit-tested. +By default, only tiny fraction of all tests are executed, so build finishes under 10 minutes. +Full test suite has over million test cases and runs for several hours/days. +To run full test suite, set `-Dmdbtest=1` VM option. +Longer unit tests might require more memory. Use this to increase heap memory assigned to unit tests: `-DtestArgLine="-Xmx3G"` +By default unit tests are executed in 3 threads. Thread count is controlled by `-DtestThreadCount=3` property +On machine with limited memory you can change fork mode so unit test consume less RAM, but run longer: `-DtestReuseForks=false` \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..583a520da --- /dev/null +++ b/build.gradle @@ -0,0 +1,67 @@ +buildscript { + + ext.kotlin_version = '1.4.10' + ext.junit_version = '5.7.0' + ext.ec_version = '10.4.0' + ext.guava_version = '28.2-jre' + + repositories { + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} +apply plugin: "kotlin" + +compileKotlin { + kotlinOptions { + jvmTarget = '1.8' + } +} + + +sourceSets { + //combine Kotlin and Java source into same dirs + main.kotlin.srcDirs += 'src/main/java' + main.java.srcDirs += 'src/main/java' + test.kotlin.srcDirs += 'src/test/java' + test.java.srcDirs += 'src/test/java' + + //include generated code into build + main.kotlin.srcDirs += 'srcGen/main/java' + main.java.srcDirs += 'srcGen/main/java' + test.kotlin.srcDirs += 'srcGen/test/java' + test.java.srcDirs += 'srcGen/test/java' + +} + +repositories { + mavenCentral() +} + + +test{ + maxParallelForks = 5 + maxHeapSize = '2G' +} + +dependencies { + compile "org.eclipse.collections:eclipse-collections-api:$ec_version" + compile "org.eclipse.collections:eclipse-collections:$ec_version" + + compile "com.google.guava:guava:$guava_version" + + compile group: 'org.jetbrains', name: 'annotations', version: '20.1.0' + + compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" + compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + + compile 'org.lz4:lz4-java:1.7.1' + + testCompile("io.kotlintest:kotlintest-runner-junit5:3.4.2") + testCompile("org.junit.vintage:junit-vintage-engine:$junit_version") + testCompile("org.junit.jupiter:junit-jupiter-api:$junit_version") + testCompile("org.junit.jupiter:junit-jupiter-engine:$junit_version") +} diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 000000000..3232f5537 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,54 @@ +buildscript { + ext.kotlin_version = '1.2.50' + + repositories { + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: "kotlin" + +compileKotlin { + kotlinOptions { +// freeCompilerArgs = ['-Xenable-jvm-default'] + jvmTarget = '1.8' + } +} + + +sourceSets { + main.kotlin.srcDirs += 'src/main/java' + main.java.srcDirs += 'src/main/java' + test.kotlin.srcDirs += 'src/test/java' + test.java.srcDirs += 'src/test/java' + + +} + +repositories { + mavenCentral() +} + + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" +} + + +task codegenClean(type: Delete) { + delete "../srcGen" +} + +task codegen(type:JavaExec) { + + dependsOn(codegenClean) + main = "MDBCodeGen" + classpath = sourceSets.main.runtimeClasspath +} + + +build.dependsOn(codegen) \ No newline at end of file diff --git a/buildSrc/src/main/java/GenMarkers.kt b/buildSrc/src/main/java/GenMarkers.kt new file mode 100644 index 000000000..e37233380 --- /dev/null +++ b/buildSrc/src/main/java/GenMarkers.kt @@ -0,0 +1,42 @@ +import java.io.File + +object GenMarkers{ + + val markers:Map = linkedMapOf( + Pair("//-WLOCK", """lock.writeLock().lock(); try{"""), + Pair("//-WUNLOCK", """}finally{lock.writeLock().unlock();}"""), + Pair("//-newRWLOCK", """java.util.concurrent.locks.ReadWriteLock lock = new java.util.concurrent.locks.ReentrantReadWriteLock();""") + ) + + fun recurJavaFiles(dir:File, f: (File) -> Unit){ + val allFiles = dir.listFiles(); + allFiles.filter { it.extension.equals("java") }.forEach(f) + allFiles.filter{it.isDirectory}.forEach{recurJavaFiles(it,f)} + } + + + // process //*-WLOCk markers + fun wlock(srcDir: File, genDir:File) { + recurJavaFiles(srcDir) { f:File-> + var content = f.readText() + + if(markers.keys.none{content.contains(it)}) { + return@recurJavaFiles + } + for ((marker, repl) in markers) { + content = content.replace(marker, repl) + } + + val oldClassName = f.nameWithoutExtension + content = content.replace("class "+oldClassName, "class ${oldClassName}RWLock") + content = content.replace(" "+oldClassName+"(", " ${oldClassName}RWLock(") + + val newFile = File(genDir.path + "/"+ f.relativeTo(srcDir).parent +"/"+ oldClassName + "RWLock.java") + + newFile.parentFile.mkdirs() + newFile.writeText(content) + + } + } + +} \ No newline at end of file diff --git a/buildSrc/src/main/java/GenRecords.kt b/buildSrc/src/main/java/GenRecords.kt new file mode 100644 index 000000000..3e4ad392e --- /dev/null +++ b/buildSrc/src/main/java/GenRecords.kt @@ -0,0 +1,154 @@ +import org.gradle.internal.impldep.org.apache.commons.io.FileUtils +import java.io.File + +object GenRecords { + + fun makeRecordMakers(dir: File){ + data class R(val type:String, val initVal:String, val ser:String){ + + val gen = if(type!="Var") "" else "" + + val isVar = type=="Var" + val isNum = type=="Int" || type=="Long" + + val extends = if(isNum)" extends Number" else "" + + fun recName() = type+"Record" + fun valType() = + if(isNum || type=="Boolean") type.toLowerCase() + else if(!isVar) type + else "E" + + + fun constParams() = if(!isVar) "" else "private final Serializer ser;" + fun newParams() = if(!isVar) "" else ", Serializer ser"; + fun newParams2() = if(!isVar) "" else ", ser" + fun constBody() = if(!isVar) "" else "this.ser=ser;" + fun newGen() = if(!isVar) "" else "" + + + + } + + val types = listOf( + R("String", "\"\"", "Serializers.STRING"), + R("Long", "0L", "Serializers.LONG"), + R("Int", "0", "Serializers.INTEGER"), + R("Boolean","false", "Serializers.BOOLEAN"), + R("Var", "null","ser") + ) + + for(t in types){ + val cont = """ + package org.mapdb.record; + + import org.mapdb.db.DB; + import org.mapdb.store.Store; + import org.mapdb.ser.Serializer; + import org.mapdb.ser.Serializers; + + public class ${t.recName()}${t.gen} ${t.extends}{ + + public static class Maker${t.gen}{ + + private final DB db; + private final String name; + + private ${t.valType()} initVal = ${t.initVal}; + + ${t.constParams()} + public Maker(DB db, String name ${t.newParams()}){ + this.db = db; + this.name = name; + ${t.constBody()} + } + + + public Maker init(${t.valType()} initialValue){ + initVal = initialValue; + return this; + } + + public ${t.recName()} make(){ + Store store = db.getStore(); + long recid = store.put(initVal, ${if(t.isVar) "ser" else t.ser}); + return new ${t.recName()}(store, recid ${t.newParams2()}); + } + + } + + + + private final Store store; + private final long recid; + ${t.constParams()} + + public ${t.recName()}(Store store, long recid ${t.newParams()}){ + this.store = store; + this.recid = recid; + ${t.constBody()} + } + + ${if(t.isNum)""" + public ${t.valType()} addAndGet(${t.valType()} i){ + return store.updateAndGet(recid, ${t.ser}, (v)-> v+i); + } + + public ${t.valType()} getAndAdd(${t.valType()} i){ + return store.getAndUpdateAtomic(recid, ${t.ser}, (v)-> v+i); + } + + public ${t.valType()} getAndDecrement(){return getAndAdd(-1);} + + public ${t.valType()} getAndIncrement(){return getAndAdd(+1);} + + public ${t.valType()} decrementAndGet(){return addAndGet(-1);} + + public ${t.valType()} incrementAndGet(){return addAndGet(+1);} + + @Override public double doubleValue(){ return (double) get();} + @Override public float floatValue(){ return (float) get();} + @Override public long longValue(){ return (long) get();} + @Override public int intValue(){ return (int) get();} +// @Override public char charValue(){ return (char) get();} + @Override public short shortValue(){ return (short) get();} + @Override public byte byteValue(){ return (byte) get();} + + """ else ""} + + //TODO hash code + + public ${t.valType()} get(){ + return store.get(recid, ${t.ser}); + } + + public void set(${t.valType()} value){ + store.update(recid, ${t.ser}, value); + } + + public ${t.valType()} getAndSet(${t.valType()} value){ + return store.getAndUpdate(recid, ${t.ser}, value); + } + + public boolean compareAndSet(${t.valType()} expectedValue, ${t.valType()} newValue){ + return store.compareAndUpdate(recid, ${t.ser}, expectedValue, newValue); + } + + @Override + public String toString(){ + return ""+get(); + } + + } + + """.trimIndent() + FileUtils.write(File(dir, t.type+"Record.java"), cont); + } + + + + + + } + +} \ No newline at end of file diff --git a/buildSrc/src/main/java/MDBCodeGen.kt b/buildSrc/src/main/java/MDBCodeGen.kt new file mode 100644 index 000000000..3e5bffc3f --- /dev/null +++ b/buildSrc/src/main/java/MDBCodeGen.kt @@ -0,0 +1,30 @@ +import org.gradle.internal.impldep.org.apache.commons.io.FileUtils +import java.io.File + +class MDBCodeGen{ + companion object { + @JvmStatic + fun main(args: Array) { + + val srcGenDir = File("../srcGen/main/java") + val srcDir = File("../src/main/java") + + val testGenDir = File("../srcGen/test/java") + + + FileUtils.write(File(srcGenDir, "AACodeGen.java"), """ +public class AACodeGen{ +} + """) + + val srcDirRecords = File(srcGenDir, "org/mapdb/record/") + srcDirRecords.mkdirs() + GenRecords.makeRecordMakers(srcDirRecords) + + GenMarkers.wlock(srcDir, srcGenDir); + + } + } + + +} \ 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 000000000..5c2d1cf01 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 new file mode 100644 index 000000000..5028f28f8 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 000000000..b0d6d0ab5 --- /dev/null +++ b/gradlew @@ -0,0 +1,188 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..9991c5032 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +: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 %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/logger.properties b/logger.properties index ba279588e..fe1016720 100644 --- a/logger.properties +++ b/logger.properties @@ -21,7 +21,9 @@ handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler # Here, the level for each package is specified. # The global level is used by default, so levels # specified here simply act as an override. -myapp.ui.level=ALL +org.mapdb.level=ALL + +#some other filtering options myapp.business.level=CONFIG myapp.data.level=SEVERE diff --git a/notice.txt b/notice.txt deleted file mode 100644 index a97c1fd79..000000000 --- a/notice.txt +++ /dev/null @@ -1,46 +0,0 @@ -MapDB -Copyright 2012-2014 Jan Kotek - -This product includes software developed by Thomas Mueller and H2 group -Relicensed under Apache License 2 with Thomas permission. -(CompressLZF.java and EncryptionXTEA.java) -Copyright (c) 2004-2011 H2 Group - - -This product includes software developed by Doug Lea and JSR 166 group: -(LongConcurrentMap.java, Atomic.java) - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - - -This product includes software developed for Apache Solr -(LongConcurrentLRUMap.java) -Copyright 2006-2014 The Apache Software Foundation - -This product includes software developed for Apache Harmony -(LongHashMap.java) -Copyright 2008-2012 The Apache Software Foundation - - -This product includes software developed by Nathen Sweet for Kryo -Relicensed under Apache License 2 (or later) with Nathans permission. -(DataInput2.packInt/Long and DataOutput.unpackInt/Long methods) -Copyright (c) 2012 Nathan Sweet - -This product includes software developed for Android project -(SerializerPojo, a few lines to invoke constructor, see comments) -//Copyright (C) 2012 The Android Open Source Project, licenced under Apache 2 license - - -This product includes software developed by Heinz Kabutz for javaspecialists.eu -(SerializerPojo, a few lines to invoke constructor, see comments) -2010-2014 Heinz Kabutz - - -Some Map unit tests are from Google Collections. -Credit goes to Jared Levy, George van den Driessche and other Google Collections developers. -Copyright (C) 2007 Google Inc. - -Luc Peuvrier wrote some unit tests for ConcurrerentNavigableMap interface. - diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 75cbd2c4a..000000000 --- a/pom.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - 4.0.0 - - org.mapdb - mapdb - 2.0.0-SNAPSHOT - mapdb - MapDB provides concurrent Maps, Sets and Queues backed by disk storage or off-heap memory. It is a fast, scalable and easy to use embedded Java database. - http://www.mapdb.org - - bundle - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - - Jan Kotek - jan - - - - - scm:git:git@github.com:jankotek/MapDB.git - scm:git:git@github.com:jankotek/MapDB.git - git@github.com:jankotek/MapDB.git - - - - UTF-8 - - - - - junit - junit - 4.11 - jar - test - false - - - - - - - org.apache.felix - maven-bundle-plugin - 2.3.7 - true - - - ${project.groupId}.${project.artifactId} - ${project.name} - ${project.version} - * - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.0 - - 1.6 - 1.6 - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-resources-plugin - 2.5 - - ${project.build.sourceEncoding} - - - - - org.apache.maven.plugins - maven-source-plugin - 2.1.2 - - - attach-sources - package - - jar - test-jar - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.16 - - - - 3 - - - **/* - - - - AAAAAAAAAA - - - - - - - - - - - - - - - reports - - - - org.jacoco - jacoco-maven-plugin - 0.6.3.201306030806 - - - - prepare-agent - report - - - - - - - - - - - - - - org.apache.maven.plugins - maven-project-info-reports-plugin - 2.7 - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9 - - - html - - javadoc - - - - - - - - - - - - - org.sonatype.oss - oss-parent - 7 - - - diff --git a/src/assembly/bin-component.xml b/src/assembly/bin-component.xml new file mode 100644 index 000000000..f51ed3371 --- /dev/null +++ b/src/assembly/bin-component.xml @@ -0,0 +1,20 @@ + + + + lib + false + runtime + + + + + diff --git a/src/assembly/bin.xml b/src/assembly/bin.xml new file mode 100644 index 000000000..869fc852c --- /dev/null +++ b/src/assembly/bin.xml @@ -0,0 +1,22 @@ + + bin + + zip + + + src/assembly/bin-component.xml + + + diff --git a/src/main/java/org/mapdb/AsyncWriteEngine.java b/src/main/java/org/mapdb/AsyncWriteEngine.java deleted file mode 100644 index a11180e78..000000000 --- a/src/main/java/org/mapdb/AsyncWriteEngine.java +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.lang.ref.WeakReference; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.LockSupport; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.logging.Level; - -/** - * {@link Engine} wrapper which provides asynchronous serialization and asynchronous write. - * This class takes an object instance, passes it to background writer thread (using Write Queue) - * where it is serialized and written to disk. Async write does not affect commit durability, - * Write Queue is flushed into disk on each commit. Modified records are held in small instance cache, - * until they are written into disk. - * - * This feature is disabled by default and can be enabled by calling {@link DBMaker#asyncWriteEnable()}. - * Write Cache is flushed in regular intervals or when it becomes full. Flush interval is 100 ms by default and - * can be controlled by {@link DBMaker#asyncWriteFlushDelay(int)}. Increasing this interval may improve performance - * in scenarios where frequently modified items should be cached, typically {@link BTreeMap} import where keys - * are presorted. - * - * Asynchronous write does not affect commit durability. Write Queue is flushed during each commit, rollback and close call. - * Those method also block until all records are written. - * You may flush Write Queue manually by using {@link org.mapdb.AsyncWriteEngine#clearCache()} method. - * There is global lock which prevents record being updated while commit is in progress. - * - * This wrapper starts one threads named {@code MapDB writer #N} (where N is static counter). - * Async Writer takes modified records from Write Queue and writes them into store. - * It also preallocates new recids, as finding empty {@code recids} takes time so small stash is pre-allocated. - * It runs as {@code daemon}, so it does not prevent JVM to exit. - * - * Asynchronous Writes have several advantages (especially for single threaded user). But there are two things - * user should be aware of: - * - * * Because data are serialized on back-ground thread, they need to be thread safe or better immutable. - * When you insert record into MapDB and modify it latter, this modification may happen before item - * was serialized and you may not be sure what version was persisted - * - * * Inter-thread communication has some overhead. - * There is also only single Writer Thread, which may create single bottle-neck. - * This usually not issue for - * single or two threads, but in multi-threaded environment it may decrease performance. - * So in truly concurrent environments with many updates (network servers, parallel computing ) - * you should keep Asynchronous Writes disabled. - * - * - * @see Engine - * @see EngineWrapper - * - * @author Jan Kotek - * - * - * - */ -public class AsyncWriteEngine extends EngineWrapper implements Engine { - - /** ensures thread name is followed by number */ - protected static final AtomicLong threadCounter = new AtomicLong(); - - - /** used to signal that object was deleted*/ - protected static final Object TOMBSTONE = new Object(); - - - protected final int maxSize; - - protected final AtomicInteger size = new AtomicInteger(); - -// protected final long[] newRecids = new long[CC.ASYNC_RECID_PREALLOC_QUEUE_SIZE]; -// protected int newRecidsPos = 0; -// protected final ReentrantLock newRecidsLock = new ReentrantLock(CC.FAIR_LOCKS); - - - /** Associates {@code recid} from Write Queue with record data and serializer. */ - protected final LongConcurrentHashMap> writeCache - = new LongConcurrentHashMap>(); - - /** Each insert to Write Queue must hold read lock. - * Commit, rollback and close operations must hold write lock - */ - protected final ReentrantReadWriteLock commitLock = new ReentrantReadWriteLock(CC.FAIR_LOCKS); - - /** number of active threads running, used to await thread termination on close */ - protected final CountDownLatch activeThreadsCount = new CountDownLatch(1); - - /** If background thread fails with exception, it is stored here, and rethrown to all callers.*/ - protected volatile Throwable threadFailedException = null; - - /** indicates that {@code close()} was called and background threads are being terminated*/ - protected volatile boolean closeInProgress = false; - - /** flush Write Queue every N milliseconds */ - protected final int asyncFlushDelay; - - protected final AtomicReference action = new AtomicReference(null); - - - - /** - * Construct new class and starts background threads. - * User may provide executor in which background tasks will be executed, - * otherwise MapDB starts two daemon threads. - * - * @param engine which stores data. - * @param _asyncFlushDelay flush Write Queue every N milliseconds - * @param executor optional executor to run tasks. If null daemon threads will be created - */ - public AsyncWriteEngine(Engine engine, int _asyncFlushDelay, int queueSize, Executor executor) { - super(engine); - this.asyncFlushDelay = _asyncFlushDelay; - this.maxSize = queueSize; - startThreads(executor); - } - - public AsyncWriteEngine(Engine engine) { - this(engine, CC.ASYNC_WRITE_FLUSH_DELAY, CC.ASYNC_WRITE_QUEUE_SIZE, null); - } - - - protected static final class WriterRunnable implements Runnable{ - - protected final WeakReference engineRef; - protected final long asyncFlushDelay; - protected final AtomicInteger size; - protected final int maxParkSize; - private final ReentrantReadWriteLock commitLock; - - - public WriterRunnable(AsyncWriteEngine engine) { - this.engineRef = new WeakReference(engine); - this.asyncFlushDelay = engine.asyncFlushDelay; - this.commitLock = engine.commitLock; - this.size = engine.size; - this.maxParkSize = engine.maxSize/4; - } - - @Override public void run() { - try{ - //run in loop - for(;;){ - - //$DELAY$ - //if conditions are right, slow down writes a bit - if(asyncFlushDelay!=0 && !commitLock.isWriteLocked() && size.get()> iter = writeCache.longMapIterator(); - while(iter.moveToNext()){ - //$DELAY$ - //usual write - final long recid = iter.key(); - Fun.Pair item = iter.value(); - //$DELAY$ - if(item == null) continue; //item was already written - if(item.a==TOMBSTONE){ - //item was not updated, but deleted - AsyncWriteEngine.super.delete(recid, item.b); - }else{ - //call update as usual - AsyncWriteEngine.super.update(recid, item.a, item.b); - } - //record has been written to underlying Engine, so remove it from cache with CAS - //$DELAY$ - if(writeCache.remove(recid, item)) { - //$DELAY$ - size.decrementAndGet(); - } - //$DELAY$ - } - }while(latch!=null && !writeCache.isEmpty()); - - - //operations such as commit,close, compact or close needs to be executed in Writer Thread - //for this case CountDownLatch is used, it also signals when operations has been completed - //CountDownLatch is used as special case to signalise special operation - if(latch!=null){ - if(CC.PARANOID && ! (writeCache.isEmpty())) - throw new AssertionError(); - //$DELAY$ - final long count = latch.getCount(); - if(count == 0){ //close operation - if(CC.LOG_EWRAP && LOG.isLoggable(Level.FINE)) - LOG.fine("Async close finished"); - return false; - }else if(count == 1){ //commit operation - //$DELAY$ - AsyncWriteEngine.super.commit(); - if(CC.LOG_EWRAP && LOG.isLoggable(Level.FINE)) - LOG.fine("Async commit finished"); - //$DELAY$ - latch.countDown(); - }else if(count==2){ //rollback operation - //$DELAY$ - AsyncWriteEngine.super.rollback(); - if(CC.LOG_EWRAP && LOG.isLoggable(Level.FINE)) - LOG.fine("Async rollback finished"); - latch.countDown(); - latch.countDown(); - }else if(count==3){ //compact operation - AsyncWriteEngine.super.compact(); - //$DELAY$ - if(CC.LOG_EWRAP && LOG.isLoggable(Level.FINE)) - LOG.fine("Async compact finished"); - latch.countDown(); - latch.countDown(); - latch.countDown(); - //$DELAY$ - }else{throw new AssertionError();} - } - //$DELAY$ - return true; - } - - - /** checks that background threads are ready and throws exception if not */ - protected void checkState() { - //$DELAY$ - if(closeInProgress) throw new IllegalAccessError("db has been closed"); - if(threadFailedException !=null) throw new RuntimeException("Writer thread failed", threadFailedException); - //$DELAY$ - } - - - - - - /** - * {@inheritDoc} - * - * Recids are managed by underlying Engine. Finding free or allocating new recids - * may take some time, so for this reason recids are preallocated by Writer Thread - * and stored in queue. This method just takes preallocated recid from queue with minimal - * delay. - * - * Newly inserted records are not written synchronously, but forwarded to background Writer Thread via queue. - * - */ - @Override - public long put(A value, Serializer serializer) { - //$DELAY$ - int size2 = 0; - long recid =0; - commitLock.readLock().lock(); - try{ - //$DELAY$ - checkState(); - recid = preallocate(); - //$DELAY$ - if(writeCache.put(recid, new Fun.Pair(value, serializer))==null) - //$DELAY$ - size2 = size.incrementAndGet(); - //$DELAY$ - }finally{ - commitLock.readLock().unlock(); - } - //$DELAY$ - if(size2>maxSize) { - //$DELAY$ - clearCache(); - } - //$DELAY$ - return recid; -} - - - /** - * {@inheritDoc} - * - * This method first looks up into Write Cache if record is not currently being written. - * If not it continues as usually - * - * - */ - @Override - public A get(long recid, Serializer serializer) { - //$DELAY$ - commitLock.readLock().lock(); - //$DELAY$ - try{ - checkState(); - //$DELAY$ - Fun.Pair item = writeCache.get(recid); - if(item!=null){ - //$DELAY$ - if(item.a == TOMBSTONE) return null; - return (A) item.a; - } - //$DELAY$ - return super.get(recid, serializer); - //$DELAY$ - }finally{ - commitLock.readLock().unlock(); - } - //$DELAY$ - } - - - /** - * {@inheritDoc} - * - * This methods forwards record into Writer Thread and returns asynchronously. - * - */ - @Override - public void update(long recid, A value, Serializer serializer) { - int size2 = 0; - //$DELAY$ - commitLock.readLock().lock(); - //$DELAY$ - try{ - checkState(); - if(writeCache.put(recid, new Fun.Pair(value, serializer))==null) { - //$DELAY$ - size2 = size.incrementAndGet(); - } - }finally{ - //$DELAY$ - commitLock.readLock().unlock(); - } - if(size2>maxSize) { - //$DELAY$ - clearCache(); - } - //$DELAY$ - } - - /** - * {@inheritDoc} - * - * This method first looks up Write Cache if record is not currently being written. - * Successful modifications are forwarded to Write Thread and method returns asynchronously. - * Asynchronicity does not affect atomicity. - */ - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - int size2 = 0; - boolean ret; - //$DELAY$ - commitLock.writeLock().lock(); - //$DELAY$ - try{ - checkState(); - Fun.Pair existing = writeCache.get(recid); - //$DELAY$ - A oldValue = existing!=null? (A) existing.a : super.get(recid, serializer); - //$DELAY$ - if(oldValue == expectedOldValue || (oldValue!=null && oldValue.equals(expectedOldValue))){ - //$DELAY$ - if(writeCache.put(recid, new Fun.Pair(newValue, serializer))==null) { - //$DELAY$ - size2 = size.incrementAndGet(); - } - ret = true; - }else{ - ret = false; - } - //$DELAY$ - }finally{ - commitLock.writeLock().unlock(); - } - //$DELAY$ - if(size2>maxSize) { - clearCache(); - } - //$DELAY$ - return ret; - } - - /** - * {@inheritDoc} - * - * This method places 'tombstone' into Write Queue so record is eventually - * deleted asynchronously. However record is visible as deleted immediately. - */ - @Override - public void delete(long recid, Serializer serializer) { - update(recid, (A) TOMBSTONE, serializer); - } - - /** - * {@inheritDoc} - * - * This method blocks until Write Queue is flushed and Writer Thread writes all records and finishes. - * When this method was called {@code closeInProgress} is set and no record can be modified. - */ - @Override - public void close() { - //$DELAY$ - commitLock.writeLock().lock(); - try { - //$DELAY$ - if(closeInProgress) return; - //$DELAY$ - checkState(); - closeInProgress = true; - //notify background threads - if(!action.compareAndSet(null,new CountDownLatch(0))) - throw new AssertionError(); - - //wait for background threads to shutdown - //$DELAY$ - while(!activeThreadsCount.await(1000,TimeUnit.MILLISECONDS)) { - //$DELAY$ - //nothing here - } - - AsyncWriteEngine.super.close(); - //$DELAY$ - } catch (InterruptedException e) { - throw new RuntimeException(e); - }finally { - commitLock.writeLock().unlock(); - } - //$DELAY$ - } - - - - protected void waitForAction(int actionNumber) { - //$DELAY$ - commitLock.writeLock().lock(); - try{ - checkState(); - //notify background threads - CountDownLatch msg = new CountDownLatch(actionNumber); - //$DELAY$ - if(!action.compareAndSet(null,msg)) - throw new AssertionError(); - //$DELAY$ - - //wait for response from writer thread - while(!msg.await(100, TimeUnit.MILLISECONDS)){ - checkState(); - } - //$DELAY$ - } catch (InterruptedException e) { - throw new RuntimeException(e); - }finally { - commitLock.writeLock().unlock(); - } - //$DELAY$ - } - - - /** - * {@inheritDoc} - * - * This method blocks until Write Queue is flushed. - * All put/update/delete methods are blocked while commit is in progress (via global ReadWrite Commit Lock). - * After this method returns, commit lock is released and other operations may continue - */ - @Override - public void commit() { - waitForAction(1); - } - - /** - * {@inheritDoc} - * - * This method blocks until Write Queue is cleared. - * All put/update/delete methods are blocked while rollback is in progress (via global ReadWrite Commit Lock). - * After this method returns, commit lock is released and other operations may continue - */ - @Override - public void rollback() { - waitForAction(2); - } - - /** - * {@inheritDoc} - * - * This method blocks all put/update/delete operations until it finishes (via global ReadWrite Commit Lock). - * - */ - @Override - public void compact() { - waitForAction(3); - } - - - /** - * {@inheritDoc} - * - * This method blocks until Write Queue is empty (written into disk). - * It also blocks any put/update/delete operations until it finishes (via global ReadWrite Commit Lock). - */ - @Override - public void clearCache() { - //$DELAY$ - commitLock.writeLock().lock(); - try{ - checkState(); - //wait for response from writer thread - while(!writeCache.isEmpty()){ - checkState(); - Thread.sleep(100); - } - //$DELAY$ - } catch (InterruptedException e) { - throw new RuntimeException(e); - }finally { - commitLock.writeLock().unlock(); - } - //$DELAY$ - super.clearCache(); - } - -} diff --git a/src/main/java/org/mapdb/BTreeKeySerializer.java b/src/main/java/org/mapdb/BTreeKeySerializer.java deleted file mode 100644 index 245fa85d4..000000000 --- a/src/main/java/org/mapdb/BTreeKeySerializer.java +++ /dev/null @@ -1,2076 +0,0 @@ -package org.mapdb; - -import java.io.*; -import java.util.Arrays; -import java.util.Comparator; -import java.util.UUID; - -/** - * Custom serializer for BTreeMap keys which enables [Delta encoding](https://en.wikipedia.org/wiki/Delta_encoding). - * - * Keys in BTree Nodes are sorted, this enables number of tricks to save disk space. - * For example for numbers we may store only difference between subsequent numbers, for string we can only take suffix, etc... - * - * @param type of key - * @param type of object which holds multiple keys ( - */ -public abstract class BTreeKeySerializer{ - - - /** - * Serialize keys from single BTree Node. - * - * @param out output stream where to put ata - * @param keys An object which represents keys - * - * @throws IOException - */ - public abstract void serialize(DataOutput out, KEYS keys) throws IOException; - - /** - * Deserializes keys for single BTree Node. To - * - * @param in input stream to read data from - * @return an object which represents keys - * - * @throws IOException - */ - public abstract KEYS deserialize(DataInput in, int nodeSize) throws IOException; - - - public abstract int compare(KEYS keys, int pos1, int pos2); - - - public abstract int compare(KEYS keys, int pos, KEY key); - - public boolean compareIsSmaller(KEYS keys, int pos, KEY key) { - //TODO override in Strings and other implementations - return compare(keys,pos,key)<0; - } - - - public abstract KEY getKey(KEYS keys, int pos); - - - public static final BTreeKeySerializer BASIC = new BTreeKeySerializer.BasicKeySerializer(Serializer.BASIC, Fun.COMPARATOR); - - public abstract Comparator comparator(); - - public abstract KEYS emptyKeys(); - - public abstract int length(KEYS keys); - - /** expand keys array by one and put {@code newKey} at position {@code pos} */ - public abstract KEYS putKey(KEYS keys, int pos, KEY newKey); - - - public abstract KEYS copyOfRange(KEYS keys, int from, int to); - - public abstract KEYS deleteKey(KEYS keys, int pos); - - /** - * Find the first children node with a key equal or greater than the given key. - * If all items are smaller it returns {@code keyser.length(keys)} - */ - public int findChildren(final BTreeMap.BNode node, final Object key) { - KEYS keys = (KEYS) node.keys; - int keylen = length(keys); - int left = 0; - int right = keylen; - - int middle; - //$DELAY$ - // binary search - for(;;) { - //$DELAY$ - middle = (left + right) / 2; - if(middle==keylen) - return middle+node.leftEdgeInc(); //null is positive infinitive - if (compareIsSmaller(keys,middle, (KEY) key)) { - left = middle + 1; - } else { - right = middle; - } - if (left >= right) { - return right+node.leftEdgeInc(); - } - } - } - - public int findChildren2(final BTreeMap.BNode node, final Object key) { - KEYS keys = (KEYS) node.keys; - int keylen = length(keys); - - int left = 0; - int right = keylen; - int comp; - int middle; - //$DELAY$ - // binary search - while (true) { - //$DELAY$ - middle = (left + right) / 2; - if(middle==keylen) - return -1-(middle+node.leftEdgeInc()); //null is positive infinitive - comp = compare(keys, middle, (KEY) key); - if(comp==0){ - //try one before last, in some cases it might be duplicate of last - if(!node.isRightEdge() && middle==keylen-1 && middle>0 - && compare(keys,middle-1,(KEY)key)==0){ - middle--; - } - return middle+node.leftEdgeInc(); - } else if ( comp< 0) { - left = middle +1; - } else { - right = middle; - } - if (left >= right) { - return -1-(right+node.leftEdgeInc()); - } - } - - } - - - public abstract KEYS arrayToKeys(Object[] keys); - - public Object[] keysToArray(KEYS keys) { - //$DELAY$ - Object[] ret = new Object[length(keys)]; - for (int i = 0; i implements Serializable { - - private static final long serialVersionUID = 1654710710946309279L; - - protected final Serializer serializer; - protected final Comparator comparator; - - public BasicKeySerializer(Serializer serializer, Comparator comparator) { - if(serializer == null || comparator == null) - throw new NullPointerException(); - this.serializer = serializer; - this.comparator = comparator; - } - - /** used for deserialization*/ - BasicKeySerializer(SerializerBase serializerBase, DataInput is, SerializerBase.FastArrayList objectStack) throws IOException { - objectStack.add(this); - serializer = (Serializer) serializerBase.deserialize(is,objectStack); - comparator = (Comparator) serializerBase.deserialize(is,objectStack); - if(serializer == null || comparator == null) - throw new NullPointerException(); - } - - @Override - public void serialize(DataOutput out, Object[] keys) throws IOException { - for(Object o:keys){ - //$DELAY$ - serializer.serialize(out, o); - } - } - - @Override - public Object[] deserialize(DataInput in, int nodeSize) throws IOException { - //$DELAY$ - Object[] keys = new Object[nodeSize]; - for(int i=0;i() { - - @Override - public void serialize(DataOutput out, long[] keys) throws IOException { - long prev = keys[0]; - DataIO.packLong(out, prev); - for(int i=1;i=0;i--) { - //$DELAY$ - ret[i] = (Long) keys[i]; - } - return ret; - } - - - @Override - public long[] deleteKey(long[] keys, int pos) { - long[] keys2 = new long[keys.length-1]; - System.arraycopy(keys,0,keys2, 0, pos); - //$DELAY$ - System.arraycopy(keys, pos+1, keys2, pos, keys2.length-pos); - //$DELAY$ - return keys2; - } - - @Override - public final int findChildren(final BTreeMap.BNode node, final Object key) { - long[] keys = (long[]) node.keys; - long key2 = (Long)key; - - int left = 0; - int right = keys.length; - - int middle; - //$DELAY$ - // binary search - for(;;) { - //$DELAY$ - middle = (left + right) / 2; - if(middle==keys.length) - return middle+node.leftEdgeInc(); //null is positive infinitive - if (keys[middle]= right) { - return right+node.leftEdgeInc(); - } - } - } - - @Override - public final int findChildren2(final BTreeMap.BNode node, final Object key) { - long[] keys = (long[]) node.keys; - long key2 = (Long)key; - - int left = 0; - int right = keys.length; - int middle; - //$DELAY$ - // binary search - while (true) { - //$DELAY$ - middle = (left + right) / 2; - if(middle==keys.length) - return -1-(middle+node.leftEdgeInc()); //null is positive infinitive - - if(keys[middle]==key2){ - //try one before last, in some cases it might be duplicate of last - if(!node.isRightEdge() && middle==keys.length-1 && middle>0 - && keys[middle-1]==key2){ - middle--; - } - return middle+node.leftEdgeInc(); - } else if ( keys[middle]= right) { - return -1-(right+node.leftEdgeInc()); - } - } - } - - }; - - /** - * @deprecated use {@link org.mapdb.BTreeKeySerializer#LONG} - */ - public static final BTreeKeySerializer ZERO_OR_POSITIVE_LONG = LONG; - - /** - * Applies delta packing on {@code java.lang.Integer}. - * Difference between consequential numbers is also packed itself, so for small diffs it takes only single byte per - * number. - */ - public static final BTreeKeySerializer INTEGER = new BTreeKeySerializer() { - @Override - public void serialize(DataOutput out, int[] keys) throws IOException { - int prev = keys[0]; - DataIO.packInt(out, prev); - //$DELAY$ - for(int i=1;i=0;i--) - //$DELAY$ - ret[i] = (Integer)keys[i]; - return ret; - } - - @Override - public int[] deleteKey(int[] keys, int pos) { - int[] keys2 = new int[keys.length-1]; - System.arraycopy(keys,0,keys2, 0, pos); - //$DELAY$ - System.arraycopy(keys, pos+1, keys2, pos, keys2.length-pos); - return keys2; - } - - @Override - public final int findChildren(final BTreeMap.BNode node, final Object key) { - int[] keys = (int[]) node.keys; - int key2 = (Integer)key; - int left = 0; - int right = keys.length; - - int middle; - //$DELAY$ - // binary search - for(;;) { - //$DELAY$ - middle = (left + right) / 2; - if(middle==keys.length) - return middle+node.leftEdgeInc(); //null is positive infinitive - if (keys[middle]= right) { - return right+node.leftEdgeInc(); - } - } - } - - @Override - public final int findChildren2(final BTreeMap.BNode node, final Object key) { - int[] keys = (int[]) node.keys; - int key2 = (Integer)key; - - int left = 0; - int right = keys.length; - int middle; - //$DELAY$ - // binary search - while (true) { - //$DELAY$ - middle = (left + right) / 2; - if(middle==keys.length) - return -1-(middle+node.leftEdgeInc()); //null is positive infinitive - - if(keys[middle]==key2){ - //try one before last, in some cases it might be duplicate of last - if(!node.isRightEdge() && middle==keys.length-1 && middle>0 - && keys[middle-1]==key2){ - middle--; - } - return middle+node.leftEdgeInc(); - } else if ( keys[middle]= right) { - return -1-(right+node.leftEdgeInc()); - } - } - } - }; - - /** - * @deprecated use {@link org.mapdb.BTreeKeySerializer#INTEGER} - */ - public static final BTreeKeySerializer ZERO_OR_POSITIVE_INT = INTEGER; - - - public static final BTreeKeySerializer ARRAY2 = new ArrayKeySerializer( - new Comparator[]{Fun.COMPARATOR,Fun.COMPARATOR}, - new Serializer[]{Serializer.BASIC, Serializer.BASIC} - ); - - public static final BTreeKeySerializer ARRAY3 = new ArrayKeySerializer( - new Comparator[]{Fun.COMPARATOR,Fun.COMPARATOR,Fun.COMPARATOR}, - new Serializer[]{Serializer.BASIC, Serializer.BASIC, Serializer.BASIC} - ); - - public static final BTreeKeySerializer ARRAY4 = new ArrayKeySerializer( - new Comparator[]{Fun.COMPARATOR,Fun.COMPARATOR,Fun.COMPARATOR,Fun.COMPARATOR}, - new Serializer[]{Serializer.BASIC, Serializer.BASIC, Serializer.BASIC, Serializer.BASIC} - ); - - - public final static class ArrayKeySerializer extends BTreeKeySerializer implements Serializable{ - - private static final long serialVersionUID = 998929894238939892L; - - protected final int tsize; - protected final Comparator[] comparators; - protected final Serializer[] serializers; - - protected final Comparator comparator; - - public ArrayKeySerializer(Comparator[] comparators, Serializer[] serializers) { - if(comparators.length!=serializers.length){ - throw new IllegalArgumentException("array sizes do not match"); - } - - this.tsize = comparators.length; - this.comparators = comparators; - this.serializers = serializers; - - this.comparator = new Fun.ArrayComparator(comparators); - } - - /** used for deserialization, extra is to avoid argument collision */ - public ArrayKeySerializer(SerializerBase serializerBase, DataInput is, - SerializerBase.FastArrayList objectStack) throws IOException { - objectStack.add(this); - tsize = DataIO.unpackInt(is); - comparators = new Comparator[tsize]; - for(int i=0;i=0;j--){ - counts[j]--; - } - } - } - - @Override - public Object[] deserialize(DataInput in, int nodeSize) throws IOException { - Object[] ret = new Object[nodeSize*tsize]; - Object[] curr = new Object[tsize]; - int[] counts = new int[tsize-1]; - //$DELAY$ - for(int i=0;i=0;j--){ - counts[j]--; - } - } - - if(CC.PARANOID){ - for(int j:counts){ - if(j!=0) - throw new AssertionError(); - } - } - return ret; - - } - - @Override - public int compare(Object[] keys, int pos1, int pos2) { - pos1 *=tsize; - pos2 *=tsize; - int res; - //$DELAY$ - for(Comparator c:comparators){ - //$DELAY$ - res = c.compare(keys[pos1++],keys[pos2++]); - if(res!=0) { - return res; - } - } - return 0; - } - - @Override - public int compare(Object[] keys, int pos, Object[] tuple) { - pos*=tsize; - int len = Math.min(tuple.length, tsize); - int r; - //$DELAY$ - for(int i=0;i UUID = new BTreeKeySerializer() { - - @Override - public void serialize(DataOutput out, long[] longs) throws IOException { - //$DELAY$ - for(long l:longs){ - out.writeLong(l); - } - } - - @Override - public long[] deserialize(DataInput in, int nodeSize) throws IOException { - long[] ret= new long[nodeSize<<1]; - //$DELAY$ - for(int i=0;i127) - return true; - } - return false; - } - - public ByteArrayKeys putKey(int pos, byte[] newKey) { - byte[] bb = new byte[array.length+ newKey.length]; - int split1 = pos==0? 0: offset[pos-1]; - System.arraycopy(array,0,bb,0,split1); - //$DELAY$ - System.arraycopy(newKey,0,bb,split1,newKey.length); - System.arraycopy(array,split1,bb,split1+newKey.length,array.length-split1); - - int[] offsets = new int[offset.length+1]; - - int plus = 0; - int plusI = 0; - for(int i=0;i127) - return true; - } - return false; - } - - @Override - public void serialize(DataOutput out, int prefixLen) throws IOException { - //write rest of the suffix - outWrite(out, 0, prefixLen); - //$DELAY$ - //write suffixes - int aa = prefixLen; - for(int o:offset){ - outWrite(out, aa, o); - aa = o+prefixLen; - } - } - - private void outWrite(DataOutput out, int from, int to) throws IOException { - for(int i=from;i STRING2 = new BTreeKeySerializer() { - - @Override - public void serialize(DataOutput out, char[][] chars) throws IOException { - boolean unicode = false; - //write lengths - for(char[] b:chars){ - DataIO.packInt(out,b.length); - //$DELAY$ - if(!unicode) { - for (char cc : b) { - if (cc>127) - unicode = true; - } - } - } - - - //find common prefix - int prefixLen = commonPrefixLen(chars); - DataIO.packInt(out,(prefixLen<<1) | (unicode?1:0)); - for (int i = 0; i < prefixLen; i++) { - DataIO.packInt(out, chars[0][i]); - } - //$DELAY$ - for(char[] b:chars){ - for (int i = prefixLen; i < b.length; i++) { - DataIO.packInt(out, b[i]); - } - } - } - - @Override - public char[][] deserialize(DataInput in, int nodeSize) throws IOException { - char[][] ret = new char[nodeSize][]; - //$DELAY$ - //read lengths and init arrays - for(int i=0;i>>=1; - //$DELAY$ - for(int i=0;i=0;i--) - ret[i] = ((String)keys[i]).toCharArray(); - return ret; - } - - @Override - public char[][] deleteKey(char[][] keys, int pos) { - char[][] keys2 = new char[keys.length-1][]; - //$DELAY$ - System.arraycopy(keys,0,keys2, 0, pos); - System.arraycopy(keys, pos+1, keys2, pos, keys2.length-pos); - return keys2; - } - }; - - protected static int commonPrefixLen(byte[][] bytes) { - for(int ret=0;;ret++){ - if(bytes[0].length==ret) { - return ret; - } - byte byt = bytes[0][ret]; - for(int i=1;i STRING = new BTreeKeySerializer() { - @Override - public void serialize(DataOutput out, StringArrayKeys keys2) throws IOException { - ByteArrayKeys keys = (ByteArrayKeys) keys2; - int offset = 0; - //write sizes - for(int o:keys.offset){ - DataIO.packInt(out,(o-offset)); - offset = o; - } - //$DELAY$ - int unicode = keys2.hasUnicodeChars()?1:0; - - //find and write common prefix - int prefixLen = keys.commonPrefixLen(); - DataIO.packInt(out,(prefixLen<<1) | unicode); - keys2.serialize(out, prefixLen); - } - - @Override - public StringArrayKeys deserialize(DataInput in, int nodeSize) throws IOException { - //read data sizes - int[] offsets = new int[nodeSize]; - int old=0; - for(int i=0;i>>=1; - //$DELAY$ - return useUnicode? - new CharArrayKeys(in,offsets,prefixLen): - new ByteArrayKeys(in,offsets,prefixLen); - } - - @Override - public int compare(StringArrayKeys byteArrayKeys, int pos1, int pos2) { - return byteArrayKeys.compare(pos1,pos2); - } - - @Override - public int compare(StringArrayKeys byteArrayKeys, int pos1, String string) { - return byteArrayKeys.compare(pos1,string); - } - - - - @Override - public String getKey(StringArrayKeys byteArrayKeys, int pos) { - return byteArrayKeys.getKeyString(pos); - } - - @Override - public Comparator comparator() { - return Fun.COMPARATOR; - } - - @Override - public ByteArrayKeys emptyKeys() { - return new ByteArrayKeys(new int[0], new byte[0]); - } - - @Override - public int length(StringArrayKeys byteArrayKeys) { - return byteArrayKeys.length(); - } - - @Override - public StringArrayKeys putKey(StringArrayKeys byteArrayKeys, int pos, String string) { - return byteArrayKeys.putKey(pos,string); - } - - @Override - public StringArrayKeys arrayToKeys(Object[] keys) { - if(keys.length==0) - return emptyKeys(); - //$DELAY$ - boolean unicode = false; - - //fill offsets - int[] offsets = new int[keys.length]; - - int old=0; - for(int i=0;i BYTE_ARRAY2 = new BTreeKeySerializer() { - - @Override - public void serialize(DataOutput out, byte[][] chars) throws IOException { - //write lengths - for(byte[] b:chars){ - DataIO.packInt(out,b.length); - } - //$DELAY$ - //find common prefix - int prefixLen = commonPrefixLen(chars); - DataIO.packInt(out,prefixLen); - out.write(chars[0], 0, prefixLen); - //$DELAY$ - for(byte[] b:chars){ - out.write(b,prefixLen,b.length-prefixLen); - } - } - - @Override - public byte[][] deserialize(DataInput in, int nodeSize) throws IOException { - byte[][] ret = new byte[nodeSize][]; - - //read lengths and init arrays - for(int i=0;i=0;i--) - ret[i] = (byte[]) keys[i]; - return ret; - } - - @Override - public byte[][] deleteKey(byte[][] keys, int pos) { - byte[][] keys2 = new byte[keys.length-1][]; - System.arraycopy(keys,0,keys2, 0, pos); - //$DELAY$ - System.arraycopy(keys, pos+1, keys2, pos, keys2.length-pos); - return keys2; - } - }; - - public static final BTreeKeySerializer BYTE_ARRAY = new BTreeKeySerializer() { - @Override - public void serialize(DataOutput out, ByteArrayKeys keys) throws IOException { - int offset = 0; - //write sizes - for(int o:keys.offset){ - DataIO.packInt(out,o-offset); - offset = o; - } - //$DELAY$ - //find and write common prefix - int prefixLen = keys.commonPrefixLen(); - DataIO.packInt(out, prefixLen); - out.write(keys.array,0,prefixLen); - //$DELAY$ - //write suffixes - offset = prefixLen; - for(int o:keys.offset){ - out.write(keys.array, offset, o-offset); - offset = o+prefixLen; - } - } - - @Override - public ByteArrayKeys deserialize(DataInput in, int nodeSize) throws IOException { - //read data sizes - int[] offsets = new int[nodeSize]; - int old=0; - for(int i=0;i - * Insertion, removal, - * update, and access operations safely execute concurrently by - * multiple threads. Iterators are weakly consistent, returning - * elements reflecting the state of the map at some point at or since - * the creation of the iterator. They do not throw {@link - * ConcurrentModificationException}, and may proceed concurrently with - * other operations. Ascending key ordered views and their iterators - * are faster than descending ones. - *

- * It is possible to obtain consistent iterator by using snapshot() - * method. - *

- * All Map.Entry pairs returned by methods in this class - * and its views represent snapshots of mappings at the time they were - * produced. They do not support the Entry.setValue - * method. (Note however that it is possible to change mappings in the - * associated map using put, putIfAbsent, or - * replace, depending on exactly which effect you need.) - *

- * This collection has optional size counter. If this is enabled Map size is - * kept in {@link Atomic.Long} variable. Keeping counter brings considerable - * overhead on inserts and removals. - * If the size counter is not enabled the size method is not a constant-time operation. - * Determining the current number of elements requires a traversal of the elements. - *

- * Additionally, the bulk operations putAll, equals, and - * clear are not guaranteed to be performed - * atomically. For example, an iterator operating concurrently with a - * putAll operation might view only some of the added - * elements. NOTE: there is an optional - *

- * This class and its views and iterators implement all of the - * optional methods of the {@link Map} and {@link Iterator} - * interfaces. Like most other concurrent collections, this class does - * not permit the use of null keys or values because some - * null return values cannot be reliably distinguished from the absence of - * elements. - *

- * Theoretical design of BTreeMap is based on paper - * from Philip L. Lehman and S. Bing Yao. More practical aspects of BTreeMap implementation are based on notes - * and demo application from Thomas Dinsdale-Young. - * B-Linked-Tree used here does not require locking for read. Updates and inserts locks only one, two or three nodes. -

- * This B-Linked-Tree structure does not support removal well, entry deletion does not collapse tree nodes. Massive - * deletion causes empty nodes and performance lost. There is workaround in form of compaction process, but it is not - * implemented yet. - * - * @author Jan Kotek - * @author some parts by Doug Lea and JSR-166 group - * - * TODO links to BTree papers are not working anymore. - */ -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class BTreeMap extends AbstractMap - implements ConcurrentNavigableMap, Bind.MapWithModificationListener{ - - - protected static final Object EMPTY = new Object(); - - - /** recid under which reference to rootRecid is stored */ - protected final long rootRecidRef; - - /** Serializer used to convert keys from/into binary form. */ - protected final BTreeKeySerializer keySerializer; - - /** Serializer used to convert keys from/into binary form*/ - protected final Serializer valueSerializer; - - /** holds node level locks*/ - protected final LongConcurrentHashMap nodeLocks = new LongConcurrentHashMap(); - - /** maximal node size allowed in this BTree*/ - protected final int maxNodeSize; - - /** DB Engine in which entries are persisted */ - protected final Engine engine; - - /** is this a Map or Set? if false, entries do not have values, only keys are allowed*/ - protected final boolean hasValues; - - /** store values as part of BTree nodes */ - protected final boolean valsOutsideNodes; - - protected final List leftEdges; - - - private final KeySet keySet; - - private final EntrySet entrySet = new EntrySet(this); - - private final Values values = new Values(this); - - private final ConcurrentNavigableMap descendingMap = new DescendingMap(this, null,true, null, false); - - protected final Atomic.Long counter; - - protected final int numberOfNodeMetas; - - /** hack used for DB Catalog*/ - protected static SortedMap preinitCatalog(DB db) { - - Long rootRef = db.getEngine().get(Engine.CATALOG_RECID, Serializer.LONG); - - BTreeKeySerializer keyser = BTreeKeySerializer.STRING; - //$DELAY$ - if(rootRef==null){ - if(db.getEngine().isReadOnly()) - return Collections.unmodifiableSortedMap(new TreeMap()); - - NodeSerializer rootSerializer = new NodeSerializer(false,BTreeKeySerializer.STRING, - db.getDefaultSerializer(), 0); - BNode root = new LeafNode(keyser.emptyKeys(), true,true,false, new Object[]{}, 0); - rootRef = db.getEngine().put(root, rootSerializer); - //$DELAY$ - db.getEngine().update(Engine.CATALOG_RECID,rootRef, Serializer.LONG); - db.getEngine().commit(); - } - return new BTreeMap(db.engine,Engine.CATALOG_RECID,32,false,0, - keyser, - db.getDefaultSerializer(), - 0); - } - - - - /** if valsOutsideNodes is true, this class is used instead of values. - * It contains reference to actual value. It also supports assertions from preventing it to leak outside of Map*/ - protected static final class ValRef{ - /** reference to actual value */ - final long recid; - public ValRef(long recid) { - this.recid = recid; - } - - @Override - public boolean equals(Object obj) { - throw new IllegalAccessError(); - } - - @Override - public int hashCode() { - throw new IllegalAccessError(); - } - - @Override - public String toString() { - return "BTreeMap-ValRer["+recid+"]"; - } - } - - protected static final class ValRefSerializer implements Serializer.Trusted{ - - @Override - public void serialize(DataOutput out, ValRef value) throws IOException { - DataIO.packLong(out,value.recid); - } - - @Override - public ValRef deserialize(DataInput in, int available) throws IOException { - return new ValRef(DataIO.unpackLong(in)); - } - - @Override - public int fixedSize() { - return -1; - } - } - - /** common interface for BTree node */ - public abstract static class BNode{ - - static final int LEFT_MASK = 1; - static final int RIGHT_MASK = 1<<1; - static final int TOO_LARGE_MASK = 1<<2; - - final Object keys; - final byte flags; - - - public BNode(Object keys, boolean leftEdge, boolean rightEdge, boolean tooLarge){ - this.keys = keys; - - this.flags = (byte)( - (leftEdge?LEFT_MASK:0)| - (rightEdge?RIGHT_MASK:0)| - (tooLarge?TOO_LARGE_MASK:0) - ); - } - - - - - final public Object key(BTreeKeySerializer keyser, int pos) { - if(isLeftEdge()){ - if(pos--==0) - return null; - } - - if(pos==keyser.length(keys) && isRightEdge()) - return null; - return keyser.getKey(keys,pos); - } - - final public int keysLen(BTreeKeySerializer keyser) { - return keyser.length(keys) + leftEdgeInc() + rightEdgeInc(); - } - - final public boolean isLeftEdge(){ - return (flags&LEFT_MASK)!=0; - } - - - final public boolean isRightEdge(){ - return (flags&RIGHT_MASK)!=0; - } - - - /** @return 1 if is left edge, or 0*/ - final public int leftEdgeInc(){ - return flags&LEFT_MASK; - } - - - /** @return 1 if is right edge, or 0*/ - final public int rightEdgeInc(){ - return (flags&RIGHT_MASK)>>>1; - } - - - final public boolean isTooLarge(){ - return (flags&TOO_LARGE_MASK)!=0; - } - - public abstract boolean isLeaf(); - public abstract Object[] vals(); - - final public Object highKey(BTreeKeySerializer keyser) { - if(isRightEdge()) - return null; - return keyser.getKey(keys,keyser.length(keys)-1); - } - - - public abstract long[] child(); - public abstract long next(); - - public final int compare(final BTreeKeySerializer keyser, int pos1, int pos2){ - if(pos1==pos2) - return 0; - //$DELAY$ - if(isLeftEdge()){ - //first position is negative infinity, so everything else is bigger - //first keys is missing in array, so adjust positions - if(pos1--==0) - return -1; - if(pos2--==0) - return 1; - } - //$DELAY$ - if(isRightEdge()){ - int keysLen = keyser.length(keys); - //last position is positive infinity, so everything else is smaller - if(pos1==keysLen) - return 1; - if(pos2==keysLen) - return -1; - } - - return keyser.compare(keys,pos1,pos2); - } - - public final int compare(final BTreeKeySerializer keyser, int pos, Object second){ - if(isLeftEdge()) { - //first position is negative infinity, so everything else is bigger - //first keys is missing in array, so adjust positions - if (pos-- == 0) - return -1; - } - //$DELAY$ - if(isRightEdge() && pos==keyser.length(keys)){ - //last position is positive infinity, so everything else is smaller - return 1; - } - return keyser.compare(keys,pos,second); - } - - - public void checkStructure(BTreeKeySerializer keyser){ - //check all keys are sorted; - if(keyser==null) - return; - - int keylen = keyser.length(keys); - int end = keylen-2+rightEdgeInc(); - if(end>1){ - for(int i = 1;i<=end;i++){ - if(keyser.compare(keys,i-1, i)>=0) - throw new AssertionError("keys are not sorted: "+Arrays.toString(keyser.keysToArray(keys))); - } - } - //check last key is sorted or null - if(!isRightEdge() && keylen>2){ - if(keyser.compare(keys,keylen-2, keylen-1)>0){ - throw new AssertionError("Last key is not sorted: "+Arrays.toString(keyser.keysToArray(keys))); - } - } - } - - public abstract BNode copyAddKey(BTreeKeySerializer keyser, int pos, Object newKey, long newChild, Object newValue); - - public abstract BNode copySplitRight(BTreeKeySerializer keyser, int splitPos); - - public abstract BNode copySplitLeft(BTreeKeySerializer keyser, int splitPos, long newNext); - } - - public final static class DirNode extends BNode{ - final long[] child; - - DirNode(Object keys, boolean leftEdge, boolean rightEdge, boolean tooLarge, long[] child) { - super(keys, leftEdge, rightEdge, tooLarge); - this.child = child; - - if(CC.PARANOID) - checkStructure(null); - } - - - - @Override public boolean isLeaf() { return false;} - - @Override public Object[] vals() { return null;} - - @Override public long[] child() { return child;} - - @Override public long next() {return child[child.length-1];} - - @Override public String toString(){ - return "Dir("+leftEdgeInc()+"-"+rightEdgeInc()+"-K"+Fun.toString(keys)+", C"+Arrays.toString(child)+")"; - } - - - @Override - public void checkStructure(BTreeKeySerializer keyser) { - super.checkStructure(keyser); - - if(keyser!=null && child.length!=keysLen(keyser)) - throw new AssertionError(); - - if((isRightEdge() != (child[child.length-1]==0))) - throw new AssertionError(); - - } - - @Override - public DirNode copyAddKey(BTreeKeySerializer keyser, int pos, Object newKey, long newChild, Object newValue) { - Object keys2 = keyser.putKey(keys, pos-leftEdgeInc(), newKey); - - long[] child2 = BTreeMap.arrayLongPut(child,pos,newChild); - //$DELAY$ - return new DirNode(keys2, isLeftEdge(),isRightEdge(),false,child2); - } - - @Override - public DirNode copySplitRight(BTreeKeySerializer keyser, int splitPos) { - int keylen = keyser.length(keys); - Object keys2 = keyser.copyOfRange(keys,splitPos-leftEdgeInc(),keylen); - //$DELAY$ - long[] child2 = Arrays.copyOfRange(child,splitPos,child.length); - //$DELAY$ - return new DirNode(keys2,false,isRightEdge(),false,child2); - } - - @Override - public DirNode copySplitLeft(BTreeKeySerializer keyser, int splitPos, long newNext) { - Object keys2 = keyser.copyOfRange(keys,0,splitPos+1 - leftEdgeInc()); - //$DELAY$ - long[] child2 = Arrays.copyOf(child, splitPos+1); - child2[splitPos] = newNext; - //$DELAY$ - return new DirNode(keys2,isLeftEdge(),false,false,child2); - } - - } - - - public final static class LeafNode extends BNode{ - final Object[] vals; - final long next; - - LeafNode(Object keys, boolean leftEdge, boolean rightEdge, boolean tooLarge, Object[] vals, long next) { - super(keys,leftEdge, rightEdge, tooLarge); - this.vals = vals; - this.next = next; - - if(CC.PARANOID) - checkStructure(null); - } - - @Override public boolean isLeaf() { return true;} - - - @Override public Object[] vals() { return vals;} - - - @Override public long[] child() { return null;} - @Override public long next() {return next;} - - @Override public String toString(){ - return "Leaf("+leftEdgeInc()+"-"+rightEdgeInc()+"-"+"K"+Fun.toString(keys)+", V"+Arrays.toString(vals)+", L="+next+")"; - } - - @Override - public void checkStructure(BTreeKeySerializer keyser) { - super.checkStructure(keyser); - if((next==0)!=isRightEdge()){ - throw new AssertionError("Next link inconsistent: "+this); - } - - if(keyser!=null && (keysLen(keyser) != vals.length+2)) { - throw new AssertionError("Inconsistent vals size: " + this); - } - //$DELAY$ - for (Object val : vals) { - if (val == null) - throw new AssertionError("Val is null: " + this); - } - - } - - @Override - public LeafNode copyAddKey(BTreeKeySerializer keyser, int pos, Object newKey, long newChild, Object newValue) { - Object keys2 = keyser.putKey(keys, pos - leftEdgeInc(), newKey); - //$DELAY$ - Object[] vals2 = arrayPut(vals, pos-1, newValue); - //$DELAY$ - return new LeafNode(keys2, isLeftEdge(), isRightEdge(), false, vals2,next); - } - - @Override - public LeafNode copySplitRight(BTreeKeySerializer keyser, int splitPos) { - int keylen = keyser.length(keys); - Object keys2 = keyser.copyOfRange(keys, splitPos-leftEdgeInc(), keylen); - //$DELAY$ - Object[] vals2 = Arrays.copyOfRange(vals, splitPos, vals.length); - //$DELAY$ - return new LeafNode(keys2,false, isRightEdge(), false, vals2, next); - } - - @Override - public LeafNode copySplitLeft(BTreeKeySerializer keyser, int splitPos, long newNext) { - int keypos =splitPos+1-leftEdgeInc(); - Object keys2 = keyser.copyOfRange(keys,0,keypos); - //clone end value - Object endkey = keyser.getKey(keys2,keypos-1); - keys2 = keyser.putKey(keys2,keypos,endkey); - //$DELAY$ - Object[] vals2 = Arrays.copyOf(vals, splitPos); - //$DELAY$ - //TODO check high/low keys overlap - return new LeafNode(keys2, isLeftEdge(), false, false, vals2, newNext); - } - - public LeafNode copyChangeValue(int pos, Object value) { - Object[] vals2 = Arrays.copyOf(vals,vals.length); - vals2[pos-1] = value; - //$DELAY$ - return new LeafNode(keys, isLeftEdge(), isRightEdge(), false, vals2, next); - } - - public LeafNode copyRemoveKey(BTreeKeySerializer keyser, int pos) { - int keyPos = pos -leftEdgeInc(); - Object keys2 = keyser.deleteKey(keys,keyPos); - //$DELAY$ - Object[] vals2 = new Object[vals.length-1]; - System.arraycopy(vals,0,vals2, 0, pos-1); - System.arraycopy(vals, pos, vals2, pos-1, vals2.length-(pos-1)); - //$DELAY$ - return new LeafNode(keys2, isLeftEdge(), isRightEdge(), false, vals2, next); - } - - public LeafNode copyClear(BTreeKeySerializer keyser) { - Object[] keys2 = new Object[2-leftEdgeInc()-rightEdgeInc()]; - if(!isLeftEdge()) - keys2[0] = key(keyser,0); - //$DELAY$ - if(!isRightEdge()) - keys2[1-leftEdgeInc()] = highKey(keyser); - //$DELAY$ - return new LeafNode (keyser.arrayToKeys(keys2), isLeftEdge(), isRightEdge(), false, new Object[]{}, next); - } - } - - - protected final Serializer nodeSerializer; - - protected static final class NodeSerializer implements Serializer.Trusted{ - - protected static final int LEAF_MASK = 1<<15; - protected static final int LEFT_SHIFT = 14; - protected static final int LEFT_MASK = 1<< LEFT_SHIFT; - protected static final int RIGHT_SHIFT = 13; - protected static final int RIGHT_MASK = 1<< RIGHT_SHIFT; - protected static final int SIZE_MASK = RIGHT_MASK - 1; - - - protected final boolean hasValues; - protected final boolean valsOutsideNodes; - protected final BTreeKeySerializer keySerializer; - protected final Serializer valueSerializer; - protected final int numberOfNodeMetas; - - public NodeSerializer(boolean valsOutsideNodes, BTreeKeySerializer keySerializer, Serializer valueSerializer, int numberOfNodeMetas) { - if(CC.PARANOID && ! (keySerializer!=null)) - throw new AssertionError(); - this.hasValues = valueSerializer!=null; - this.valsOutsideNodes = valsOutsideNodes; - this.keySerializer = keySerializer; - this.valueSerializer = valsOutsideNodes? new ValRefSerializer() : valueSerializer; - this.numberOfNodeMetas = numberOfNodeMetas; - } - - @Override - public void serialize(DataOutput out, BNode value) throws IOException { - final boolean isLeaf = value.isLeaf(); - - //check node integrity in paranoid mode - if(CC.PARANOID){ - value.checkStructure(keySerializer); - } - //$DELAY$ - - final int header = - (isLeaf ? LEAF_MASK : 0) | - (value.isLeftEdge() ? LEFT_MASK : 0) | - (value.isRightEdge() ? RIGHT_MASK : 0) | - value.keysLen(keySerializer); - - out.writeShort(header); - //$DELAY$ - - //write node metas, right now this is ignored, but in future it could be used for counted btrees or aggregations - for(int i=0;i0) - keySerializer.serialize(out,value.keys); - //$DELAY$ - if(isLeaf){ - if(hasValues){ - for(Object val:value.vals()){ - valueSerializer.serialize(out, val); - } - }else{ - serializeSetFlags(out, value); - } - } - } - - public void serializeSetFlags(DataOutput out, BNode value) throws IOException { - //write bits if values are null - boolean[] bools = new boolean[value.vals().length]; - for(int i=0;i>LEFT_SHIFT; - final int right = (header& RIGHT_MASK) >>RIGHT_SHIFT; - - BNode node; - if(isLeaf){ - node = deserializeLeaf(in, size, left, right); - }else{ - node = deserializeDir(in, size, left, right); - } - //$DELAY$ - if(CC.PARANOID){ - node.checkStructure(keySerializer); - } - return node; - } - - private BNode deserializeDir(final DataInput in, final int size, final int left, final int right) throws IOException { - final long[] child = new long[size]; - for(int i=0;i valueSerializer, - int numberOfNodeMetas) { - if(maxNodeSize%2!=0) throw new IllegalArgumentException("maxNodeSize must be dividable by 2"); - if(maxNodeSize<6) throw new IllegalArgumentException("maxNodeSize too low"); - if((maxNodeSize& NodeSerializer.SIZE_MASK) !=maxNodeSize) - throw new IllegalArgumentException("maxNodeSize too high"); - if(rootRecidRef<=0||counterRecid<0 || numberOfNodeMetas<0) throw new IllegalArgumentException(); - if(keySerializer==null) throw new NullPointerException(); -// SerializerBase.assertSerializable(keySerializer); //TODO serializer serialization -// SerializerBase.assertSerializable(valueSerializer); - - this.rootRecidRef = rootRecidRef; - this.hasValues = valueSerializer!=null; - this.valsOutsideNodes = valsOutsideNodes; - this.engine = engine; - this.maxNodeSize = maxNodeSize; - this.numberOfNodeMetas = numberOfNodeMetas; - - this.keySerializer = keySerializer; - this.valueSerializer = valueSerializer; - - - this.nodeSerializer = new NodeSerializer(valsOutsideNodes,keySerializer,valueSerializer,numberOfNodeMetas); - - this.keySet = new KeySet(this, hasValues); - //$DELAY$ - - if(counterRecid!=0){ - this.counter = new Atomic.Long(engine,counterRecid); - Bind.size(this,counter); - }else{ - this.counter = null; - } - - //load left edge refs - ArrayList leftEdges2 = new ArrayList(); - long r = engine.get(rootRecidRef,Serializer.LONG); - for(;;){ - //$DELAY$ - BNode n= engine.get(r,nodeSerializer); - leftEdges2.add(r); - if(n.isLeaf()) break; - r = n.child()[0]; - } - //$DELAY$ - Collections.reverse(leftEdges2); - leftEdges = new CopyOnWriteArrayList(leftEdges2); - } - - /** creates empty root node and returns recid of its reference*/ - static protected long createRootRef(Engine engine, BTreeKeySerializer keySer, Serializer valueSer, int numberOfNodeMetas){ - final LeafNode emptyRoot = new LeafNode(keySer.emptyKeys(), true,true, false,new Object[]{}, 0); - //empty root is serializer simpler way, so we can use dummy values - long rootRecidVal = engine.put(emptyRoot, new NodeSerializer(false,keySer, valueSer, numberOfNodeMetas)); - return engine.put(rootRecidVal,Serializer.LONG); - } - - - - - - @Override - public V get(Object key){ - return (V) get(key, true); - } - - protected Object get(Object key, boolean expandValue) { - if(key==null) throw new NullPointerException(); - K v = (K) key; - long current = engine.get(rootRecidRef, Serializer.LONG); //get root - //$DELAY$ - BNode A = engine.get(current, nodeSerializer); - - //dive until leaf - while(!A.isLeaf()){ - //$DELAY$ - current = nextDir((DirNode) A, v); - //$DELAY$ - A = engine.get(current, nodeSerializer); - } - - for(;;) { - int pos = keySerializer.findChildren2(A, key); - //$DELAY$ - if (pos > 0 && pos != A.keysLen(keySerializer) - 1) { - //found - Object val = A.vals()[pos - 1]; - //$DELAY$ - if(expandValue) - val = valExpand(val); - return val; - } else if (pos <= 0 && -pos - 1 != A.keysLen(keySerializer) - 1) { - //$DELAY$ - //not found - return null; - } else { - //move to next link - current = A.next(); - //$DELAY$ - if (current == 0) { - return null; - } - A = engine.get(current, nodeSerializer); - } - } - - } - - protected V valExpand(Object ret) { - if(valsOutsideNodes && ret!=null) { - long recid = ((ValRef)ret).recid; - //$DELAY$ - ret = engine.get(recid, valueSerializer); - } - return (V) ret; - } - - protected final long nextDir(DirNode d, Object key) { - int pos = keySerializer.findChildren(d, key) - 1; - //$DELAY$ - if(pos<0) pos = 0; - return d.child[pos]; - } - - - @Override - public V put(K key, V value){ - if(key==null||value==null) throw new NullPointerException(); - return put2(key,value, false); - } - - protected V put2(final K key, final V value2, final boolean putOnlyIfAbsent){ - K v = key; - - V value = value2; - if(valsOutsideNodes){ - long recid = engine.put(value2, valueSerializer); - //$DELAY$ - value = (V) new ValRef(recid); - } - - int stackPos = -1; - long[] stackVals = new long[4]; - - final long rootRecid = engine.get(rootRecidRef, Serializer.LONG); - long current = rootRecid; - //$DELAY$ - BNode A = engine.get(current, nodeSerializer); - while(!A.isLeaf()){ - //$DELAY$ - long t = current; - current = nextDir((DirNode) A, v); - //$DELAY$ - if(CC.PARANOID && ! (current>0) ) - throw new AssertionError(A); - //if is not link - if (current != A.next()) { - //stack push t - stackPos++; - if(stackVals.length == stackPos) //grow if needed - stackVals = Arrays.copyOf(stackVals, stackVals.length*2); - //$DELAY$ - stackVals[stackPos] = t; - } - //$DELAY$ - A = engine.get(current, nodeSerializer); - } - int level = 1; - - long p=0; - try{ - while(true){ - //$DELAY$ - boolean found; - do{ - //$DELAY$ - lock(nodeLocks, current); - //$DELAY$ - found = true; - A = engine.get(current, nodeSerializer); - int pos = keySerializer.findChildren(A, v); - //check if keys is already in tree - //$DELAY$ - if(pos highvalue(a) - if(!A.isRightEdge() && A.compare(keySerializer,A.keysLen(keySerializer)-1,v)<0){ - //$DELAY$ - //follow link until necessary - unlock(nodeLocks, current); - found = false; - //$DELAY$ - int pos2 = keySerializer.findChildren(A, v); - while(A!=null && pos2 == A.keysLen(keySerializer)){ - //TODO lock? - long next = A.next(); - //$DELAY$ - if(next==0) break; - current = next; - A = engine.get(current, nodeSerializer); - //$DELAY$ - pos2 = keySerializer.findChildren(A, v); - } - - } - - - }while(!found); - - int pos = keySerializer.findChildren(A, v); - //$DELAY$ - A = A.copyAddKey(keySerializer,pos,v,p,value); - //$DELAY$ - // can be new item inserted into A without splitting it? - if(A.keysLen(keySerializer) - (A.isLeaf()?1:0)0)) - throw new AssertionError(); - }else{ - BNode R = new DirNode( - keySerializer.arrayToKeys(new Object[]{A.highKey(keySerializer)}), - true,true,false, - new long[]{current,q, 0}); - //$DELAY$ - lock(nodeLocks, rootRecidRef); - //$DELAY$ - unlock(nodeLocks, current); - //$DELAY$ - long newRootRecid = engine.put(R, nodeSerializer); - //$DELAY$ - if(CC.PARANOID && ! (nodeLocks.get(rootRecidRef)==Thread.currentThread())) - throw new AssertionError(); - engine.update(rootRecidRef, newRootRecid, Serializer.LONG); - //add newRootRecid into leftEdges - leftEdges.add(newRootRecid); - - notify(key, null, value2); - //$DELAY$ - unlock(nodeLocks, rootRecidRef); - //$DELAY$ - if(CC.PARANOID) assertNoLocks(nodeLocks); - //$DELAY$ - return null; - } - } - } - }catch(RuntimeException e){ - unlockAll(nodeLocks); - throw e; - }catch(Exception e){ - unlockAll(nodeLocks); - throw new RuntimeException(e); - } - } - - - protected static class BTreeIterator{ - final BTreeMap m; - - LeafNode currentLeaf; - Object lastReturnedKey; - int currentPos; - final Object hi; - final boolean hiInclusive; - - /** unbounded iterator*/ - BTreeIterator(BTreeMap m){ - this.m = m; - hi=null; - hiInclusive=false; - pointToStart(); - } - - /** bounder iterator, args may be null for partially bounded*/ - BTreeIterator(BTreeMap m, Object lo, boolean loInclusive, Object hi, boolean hiInclusive){ - this.m = m; - if(lo==null){ - //$DELAY$ - pointToStart(); - }else{ - //$DELAY$ - Fun.Pair l = m.findLargerNode(lo, loInclusive); - currentPos = l!=null? l.a : -1; - currentLeaf = l!=null ? l.b : null; - } - this.hi = hi; - this.hiInclusive = hiInclusive; - //$DELAY$ - if(hi!=null && currentLeaf!=null){ - //check in bounds - int c = currentLeaf.compare(m.keySerializer,currentPos,hi); - if (c > 0 || (c == 0 && !hiInclusive)){ - //out of high bound - currentLeaf=null; - currentPos=-1; - //$DELAY$ - } - } - - } - - - private void pointToStart() { - //find left-most leaf - final long rootRecid = m.engine.get(m.rootRecidRef, Serializer.LONG); - BNode node = (BNode) m.engine.get(rootRecid, m.nodeSerializer); - //$DELAY$ - while(!node.isLeaf()){ - //$DELAY$ - node = (BNode) m.engine.get(node.child()[0], m.nodeSerializer); - } - currentLeaf = (LeafNode) node; - currentPos = 1; - //$DELAY$ - while(currentLeaf.keysLen(m.keySerializer)==2){ - //follow link until leaf is not empty - if(currentLeaf.next == 0){ - //$DELAY$ - currentLeaf = null; - return; - } - //$DELAY$ - currentLeaf = (LeafNode) m.engine.get(currentLeaf.next, m.nodeSerializer); - } - } - - - public boolean hasNext(){ - return currentLeaf!=null; - } - - public void remove(){ - if(lastReturnedKey==null) throw new IllegalStateException(); - m.remove(lastReturnedKey); - //$DELAY$ - lastReturnedKey = null; - } - - protected void advance(){ - if(currentLeaf==null) return; - lastReturnedKey = currentLeaf.key(m.keySerializer,currentPos); - currentPos++; - //$DELAY$ - if(currentPos == currentLeaf.keysLen(m.keySerializer)-1){ - //move to next leaf - if(currentLeaf.next==0){ - currentLeaf = null; - currentPos=-1; - return; - } - //$DELAY$ - currentPos = 1; - currentLeaf = (LeafNode) m.engine.get(currentLeaf.next, m.nodeSerializer); - while(currentLeaf.keysLen(m.keySerializer)==2){ - if(currentLeaf.next ==0){ - currentLeaf = null; - currentPos=-1; - return; - } - currentLeaf = (LeafNode) m.engine.get(currentLeaf.next, m.nodeSerializer); - //$DELAY$ - } - } - if(hi!=null && currentLeaf!=null){ - //check in bounds - int c = currentLeaf.compare(m.keySerializer,currentPos,hi); - if (c > 0 || (c == 0 && !hiInclusive)){ - //$DELAY$ - //out of high bound - currentLeaf=null; - currentPos=-1; - } - } - } - } - - @Override - public V remove(Object key) { - return removeOrReplace(key, null, null); - } - - private V removeOrReplace(final Object key, final Object value, final Object putNewValue) { - if(key==null) - throw new NullPointerException("null key"); - long current = engine.get(rootRecidRef, Serializer.LONG); - - BNode A = engine.get(current, nodeSerializer); - //$DELAY$ - while(!A.isLeaf()){ - //$DELAY$ - current = nextDir((DirNode) A, key); - A = engine.get(current, nodeSerializer); - } - - long old =0; - try{for(;;){ - //$DELAY$ - lock(nodeLocks, current); - //$DELAY$ - if(old!=0) { - //$DELAY$ - unlock(nodeLocks, old); - } - A = engine.get(current, nodeSerializer); - //$DELAY$ - int pos = keySerializer.findChildren2(A, key); -// System.out.println(key+" - "+pos+" - "+A); - if(pos>0 && pos!=A.keysLen(keySerializer)-1){ - //found, delete from node - //$DELAY$ - Object oldVal = A.vals()[pos-1]; - oldVal = valExpand(oldVal); - if(value!=null && !value.equals(oldVal)){ - unlock(nodeLocks, current); - //$DELAY$ - return null; - } - - Object putNewValueOutside = putNewValue; - if(putNewValue!=null && valsOutsideNodes){ - //$DELAY$ - long recid = engine.put((V)putNewValue,valueSerializer); - //$DELAY$ - putNewValueOutside = new ValRef(recid); - } - - A = putNewValue!=null? - ((LeafNode)A).copyChangeValue(pos,putNewValueOutside): - ((LeafNode)A).copyRemoveKey(keySerializer,pos); - if(CC.PARANOID && ! (nodeLocks.get(current)==Thread.currentThread())) - throw new AssertionError(); - //$DELAY$ - engine.update(current, A, nodeSerializer); - notify((K)key, (V)oldVal, (V)putNewValue); - unlock(nodeLocks, current); - return (V) oldVal; - }else if(pos<=0 && -pos-1!=A.keysLen(keySerializer)-1){ - //not found - unlock(nodeLocks, current); - //$DELAY$ - return null; - }else{ - //move to next link - old = current; - current = A.next(); - //$DELAY$ - if(current==0){ - //end reached - unlock(nodeLocks,old); - return null; - } - } - - } - }catch(RuntimeException e){ - unlockAll(nodeLocks); - throw e; - }catch(Exception e){ - unlockAll(nodeLocks); - throw new RuntimeException(e); - } - } - - - @Override - public void clear() { - boolean hasListeners = modListeners.length>0; - long current = engine.get(rootRecidRef, Serializer.LONG); - - BNode A = engine.get(current, nodeSerializer); - //$DELAY$ - while(!A.isLeaf()){ - current = A.child()[0]; - //$DELAY$ - A = engine.get(current, nodeSerializer); - } - - long old =0; - try{for(;;) { - //$DELAY$ - //lock nodes - lock(nodeLocks, current); - if (old != 0) { - //$DELAY$ - unlock(nodeLocks, old); - } - //$DELAY$ - //notify about deletion - int size = A.keysLen(keySerializer)-1; - if(hasListeners) { - //$DELAY$ - for (int i = 1; i < size; i++) { - Object val = (V) A.vals()[i - 1]; - val = valExpand(val); - //$DELAY$ - notify((K) A.key(keySerializer,i),(V) val, null); - } - } - - //remove all node content - A = ((LeafNode) A).copyClear(keySerializer); - //$DELAY$ - engine.update(current, A, nodeSerializer); - - //move to next link - old = current; - //$DELAY$ - current = A.next(); - if (current == 0) { - //end reached - //$DELAY$ - unlock(nodeLocks, old); - //$DELAY$ - return; - } - //$DELAY$ - A = engine.get(current, nodeSerializer); - } - }catch(RuntimeException e){ - unlockAll(nodeLocks); - throw e; - }catch(Exception e){ - unlockAll(nodeLocks); - throw new RuntimeException(e); - } - - } - - - static class BTreeKeyIterator extends BTreeIterator implements Iterator{ - - BTreeKeyIterator(BTreeMap m) { - super(m); - } - - BTreeKeyIterator(BTreeMap m, Object lo, boolean loInclusive, Object hi, boolean hiInclusive) { - super(m, lo, loInclusive, hi, hiInclusive); - } - - @Override - public K next() { - if(currentLeaf == null) throw new NoSuchElementException(); - K ret = (K) currentLeaf.key(m.keySerializer,currentPos); - //$DELAY$ - advance(); - //$DELAY$ - return ret; - } - } - - static class BTreeValueIterator extends BTreeIterator implements Iterator{ - - BTreeValueIterator(BTreeMap m) { - super(m); - } - - BTreeValueIterator(BTreeMap m, Object lo, boolean loInclusive, Object hi, boolean hiInclusive) { - super(m, lo, loInclusive, hi, hiInclusive); - } - - @Override - public V next() { - if(currentLeaf == null) throw new NoSuchElementException(); - Object ret = currentLeaf.vals[currentPos-1]; - //$DELAY$ - advance(); - //$DELAY$ - return (V) m.valExpand(ret); - } - - } - - static class BTreeEntryIterator extends BTreeIterator implements Iterator>{ - - BTreeEntryIterator(BTreeMap m) { - super(m); - } - - BTreeEntryIterator(BTreeMap m, Object lo, boolean loInclusive, Object hi, boolean hiInclusive) { - super(m, lo, loInclusive, hi, hiInclusive); - } - - @Override - public Entry next() { - if(currentLeaf == null) throw new NoSuchElementException(); - K ret = (K) currentLeaf.key(m.keySerializer,currentPos); - Object val = currentLeaf.vals[currentPos-1]; - //$DELAY$ - advance(); - //$DELAY$ - return m.makeEntry(ret, m.valExpand(val)); - } - } - - - - - - - protected Entry makeEntry(Object key, Object value) { - if(CC.PARANOID && ! (!(value instanceof ValRef))) - throw new AssertionError(); - return new SimpleImmutableEntry((K)key, (V)value); - } - - - @Override - public boolean isEmpty() { - return !keyIterator().hasNext(); - } - - @Override - public int size() { - long size = sizeLong(); - if(size>Integer.MAX_VALUE) return Integer.MAX_VALUE; - return (int) size; - } - - @Override - public long sizeLong() { - if(counter!=null) - return counter.get(); - - long size = 0; - BTreeIterator iter = new BTreeIterator(this); - //$DELAY$ - while(iter.hasNext()){ - //$DELAY$ - iter.advance(); - size++; - } - return size; - } - - @Override - public V putIfAbsent(K key, V value) { - if(key == null || value == null) throw new NullPointerException(); - return put2(key, value, true); - } - - @Override - public boolean remove(Object key, Object value) { - if(key == null) throw new NullPointerException(); - return value != null && removeOrReplace(key, value, null) != null; - } - - @Override - public boolean replace(final K key, final V oldValue, final V newValue) { - if(key == null || oldValue == null || newValue == null ) throw new NullPointerException(); - - return removeOrReplace(key,oldValue,newValue)!=null; - } - - @Override - public V replace(final K key, final V value) { - if(key == null || value == null) throw new NullPointerException(); - - return removeOrReplace(key, null, value); - } - - - @Override - public Comparator comparator() { - return keySerializer.comparator(); - } - - - @Override - public Map.Entry firstEntry() { - final long rootRecid = engine.get(rootRecidRef, Serializer.LONG); - BNode n = engine.get(rootRecid, nodeSerializer); - //$DELAY$ - while(!n.isLeaf()){ - //$DELAY$ - n = engine.get(n.child()[0], nodeSerializer); - } - LeafNode l = (LeafNode) n; - //follow link until necessary - while(l.keysLen(keySerializer)==2){ - if(l.next==0) return null; - //$DELAY$ - l = (LeafNode) engine.get(l.next, nodeSerializer); - } - //$DELAY$ - return makeEntry(l.key(keySerializer,1), valExpand(l.vals[0])); - } - - - @Override - public Entry pollFirstEntry() { - //$DELAY$ - while(true){ - //$DELAY$ - Entry e = firstEntry(); - //$DELAY$ - if(e==null || remove(e.getKey(),e.getValue())){ - return e; - } - } - } - - @Override - public Entry pollLastEntry() { - //$DELAY$ - while(true){ - Entry e = lastEntry(); - //$DELAY$ - if(e==null || remove(e.getKey(),e.getValue())){ - return e; - } - } - } - - - protected Entry findSmaller(K key,boolean inclusive){ - if(key==null) throw new NullPointerException(); - final long rootRecid = engine.get(rootRecidRef, Serializer.LONG); - //$DELAY$ - BNode n = engine.get(rootRecid, nodeSerializer); - //$DELAY$ - Entry k = findSmallerRecur(n, key, inclusive); - //$DELAY$ - if(k==null || (k.getValue()==null)) return null; - return k; - } - - private Entry findSmallerRecur(BNode n, K key, boolean inclusive) { - //TODO optimize comparation in this method - final boolean leaf = n.isLeaf(); - final int start = leaf ? n.keysLen(keySerializer)-2 : n.keysLen(keySerializer)-1; - final int end = leaf?1:0; - final int res = inclusive? 1 : 0; - //$DELAY$ - for(int i=start;i>=end; i--){ - //$DELAY$ - final Object key2 = n.key(keySerializer,i); - int comp = (key2==null)? -1 : keySerializer.comparator().compare(key2, key); - if(comp ret = findSmallerRecur(n2, key, inclusive); - if(ret!=null) return ret; - } - } - } - - return null; - } - - - @Override - public Map.Entry lastEntry() { - final long rootRecid = engine.get(rootRecidRef, Serializer.LONG); - BNode n = engine.get(rootRecid, nodeSerializer); - //$DELAY$ - Entry e = lastEntryRecur(n); - if(e!=null && e.getValue()==null) return null; - return e; - } - - - private Map.Entry lastEntryRecur(BNode n){ - if(n.isLeaf()){ - //follow next node if available - if(n.next()!=0){ - BNode n2 = engine.get(n.next(), nodeSerializer); - Map.Entry ret = lastEntryRecur(n2); - //$DELAY$ - if(ret!=null) - return ret; - } - - //iterate over keys to find last non null key - for(int i=n.keysLen(keySerializer)-2; i>0;i--){ - Object k = n.key(keySerializer,i); - if(k!=null && n.vals().length>0) { - Object val = valExpand(n.vals()[i-1]); - //$DELAY$ - if(val!=null){ - //$DELAY$ - return makeEntry(k, val); - } - } - } - }else{ - //dir node, dive deeper - for(int i=n.child().length-1; i>=0;i--){ - long childRecid = n.child()[i]; - if(childRecid==0) continue; - BNode n2 = engine.get(childRecid, nodeSerializer); - //$DELAY$ - Entry ret = lastEntryRecur(n2); - //$DELAY$ - if(ret!=null) - return ret; - } - } - return null; - } - - @Override - public Map.Entry lowerEntry(K key) { - if(key==null) throw new NullPointerException(); - return findSmaller(key, false); - } - - @Override - public K lowerKey(K key) { - Entry n = lowerEntry(key); - return (n == null)? null : n.getKey(); - } - - @Override - public Map.Entry floorEntry(K key) { - if(key==null) throw new NullPointerException(); - return findSmaller(key, true); - } - - @Override - public K floorKey(K key) { - Entry n = floorEntry(key); - return (n == null)? null : n.getKey(); - } - - @Override - public Map.Entry ceilingEntry(K key) { - if(key==null) throw new NullPointerException(); - return findLarger(key, true); - } - - protected Entry findLarger(final K key, boolean inclusive) { - if(key==null) return null; - - long current = engine.get(rootRecidRef, Serializer.LONG); - - BNode A = engine.get(current, nodeSerializer); - - //dive until leaf - //$DELAY$ - while(!A.isLeaf()){ - current = nextDir((DirNode) A, key); - //$DELAY$ - A = engine.get(current, nodeSerializer); - } - - //now at leaf level - LeafNode leaf = (LeafNode) A; - //follow link until first matching node is found - final int comp = inclusive?1:0; - //$DELAY$ - while(true){ - //$DELAY$ - for(int i=1;i findLargerNode(final K key, boolean inclusive) { - if(key==null) return null; - - long current = engine.get(rootRecidRef, Serializer.LONG); - //$DELAY$ - BNode A = engine.get(current, nodeSerializer); - - //dive until leaf - while(!A.isLeaf()){ - current = nextDir((DirNode) A, key); - A = engine.get(current, nodeSerializer); - } - - //now at leaf level - LeafNode leaf = (LeafNode) A; - //follow link until first matching node is found - final int comp = inclusive?1:0; - while(true){ - //$DELAY$ - for(int i=1;i n = ceilingEntry(key); - return (n == null)? null : n.getKey(); - } - - @Override - public Map.Entry higherEntry(K key) { - if(key==null) throw new NullPointerException(); - return findLarger(key, false); - } - - @Override - public K higherKey(K key) { - if(key==null) throw new NullPointerException(); - Entry n = higherEntry(key); - return (n == null)? null : n.getKey(); - } - - @Override - public boolean containsKey(Object key) { - if(key==null) throw new NullPointerException(); - return get(key, false)!=null; - } - - @Override - public boolean containsValue(Object value){ - if(value ==null) throw new NullPointerException(); - Iterator valueIter = valueIterator(); - //$DELAY$ - while(valueIter.hasNext()){ - //$DELAY$ - if(value.equals(valueIter.next())) - return true; - } - return false; - } - - - @Override - public K firstKey() { - Entry e = firstEntry(); - if(e==null) throw new NoSuchElementException(); - return e.getKey(); - } - - @Override - public K lastKey() { - Entry e = lastEntry(); - if(e==null) throw new NoSuchElementException(); - return e.getKey(); - } - - - @Override - public ConcurrentNavigableMap subMap(K fromKey, - boolean fromInclusive, - K toKey, - boolean toInclusive) { - if (fromKey == null || toKey == null) - throw new NullPointerException(); - return new SubMap - ( this, fromKey, fromInclusive, toKey, toInclusive); - } - - @Override - public ConcurrentNavigableMap headMap(K toKey, - boolean inclusive) { - if (toKey == null) - throw new NullPointerException(); - return new SubMap - (this, null, false, toKey, inclusive); - } - - @Override - public ConcurrentNavigableMap tailMap(K fromKey, - boolean inclusive) { - if (fromKey == null) - throw new NullPointerException(); - return new SubMap - (this, fromKey, inclusive, null, false); - } - - @Override - public ConcurrentNavigableMap subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public ConcurrentNavigableMap headMap(K toKey) { - return headMap(toKey, false); - } - - @Override - public ConcurrentNavigableMap tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - - Iterator keyIterator() { - return new BTreeKeyIterator(this); - } - - Iterator valueIterator() { - return new BTreeValueIterator(this); - } - - Iterator> entryIterator() { - return new BTreeEntryIterator(this); - } - - - /* ---------------- View methods -------------- */ - - @Override - public NavigableSet keySet() { - return keySet; - } - - @Override - public NavigableSet navigableKeySet() { - return keySet; - } - - @Override - public Collection values() { - return values; - } - - @Override - public Set> entrySet() { - return entrySet; - } - - @Override - public ConcurrentNavigableMap descendingMap() { - return descendingMap; - } - - @Override - public NavigableSet descendingKeySet() { - return descendingMap.keySet(); - } - - static List toList(Collection c) { - // Using size() here would be a pessimization. - List list = new ArrayList(); - for (E e : c){ - list.add(e); - } - return list; - } - - - - static final class KeySet extends AbstractSet implements NavigableSet { - - protected final ConcurrentNavigableMap m; - private final boolean hasValues; - KeySet(ConcurrentNavigableMap map, boolean hasValues) { - m = map; - this.hasValues = hasValues; - } - @Override - public int size() { return m.size(); } - @Override - public boolean isEmpty() { return m.isEmpty(); } - @Override - public boolean contains(Object o) { return m.containsKey(o); } - @Override - public boolean remove(Object o) { return m.remove(o) != null; } - @Override - public void clear() { m.clear(); } - @Override - public E lower(E e) { return m.lowerKey(e); } - @Override - public E floor(E e) { return m.floorKey(e); } - @Override - public E ceiling(E e) { return m.ceilingKey(e); } - @Override - public E higher(E e) { return m.higherKey(e); } - @Override - public Comparator comparator() { return m.comparator(); } - @Override - public E first() { return m.firstKey(); } - @Override - public E last() { return m.lastKey(); } - @Override - public E pollFirst() { - Map.Entry e = m.pollFirstEntry(); - return e == null? null : e.getKey(); - } - @Override - public E pollLast() { - Map.Entry e = m.pollLastEntry(); - return e == null? null : e.getKey(); - } - @Override - public Iterator iterator() { - if (m instanceof BTreeMap) - return ((BTreeMap)m).keyIterator(); - else if(m instanceof SubMap) - return ((BTreeMap.SubMap)m).keyIterator(); - else - return ((BTreeMap.DescendingMap)m).keyIterator(); - } - @Override - public boolean equals(Object o) { - if (o == this) - return true; - if (!(o instanceof Set)) - return false; - Collection c = (Collection) o; - try { - return containsAll(c) && c.containsAll(this); - } catch (ClassCastException unused) { - return false; - } catch (NullPointerException unused) { - return false; - } - } - @Override - public Object[] toArray() { return toList(this).toArray(); } - @Override - public T[] toArray(T[] a) { return toList(this).toArray(a); } - @Override - public Iterator descendingIterator() { - return descendingSet().iterator(); - } - @Override - public NavigableSet subSet(E fromElement, - boolean fromInclusive, - E toElement, - boolean toInclusive) { - return new KeySet(m.subMap(fromElement, fromInclusive, - toElement, toInclusive),hasValues); - } - @Override - public NavigableSet headSet(E toElement, boolean inclusive) { - return new KeySet(m.headMap(toElement, inclusive),hasValues); - } - @Override - public NavigableSet tailSet(E fromElement, boolean inclusive) { - return new KeySet(m.tailMap(fromElement, inclusive),hasValues); - } - @Override - public NavigableSet subSet(E fromElement, E toElement) { - return subSet(fromElement, true, toElement, false); - } - @Override - public NavigableSet headSet(E toElement) { - return headSet(toElement, false); - } - @Override - public NavigableSet tailSet(E fromElement) { - return tailSet(fromElement, true); - } - @Override - public NavigableSet descendingSet() { - return new KeySet(m.descendingMap(),hasValues); - } - - @Override - public boolean add(E k) { - if(hasValues) - throw new UnsupportedOperationException(); - else - return m.put(k, EMPTY ) == null; - } - } - - static final class Values extends AbstractCollection { - private final ConcurrentNavigableMap m; - Values(ConcurrentNavigableMap map) { - m = map; - } - @Override - public Iterator iterator() { - if (m instanceof BTreeMap) - return ((BTreeMap)m).valueIterator(); - else - return ((SubMap)m).valueIterator(); - } - @Override - public boolean isEmpty() { - return m.isEmpty(); - } - @Override - public int size() { - return m.size(); - } - @Override - public boolean contains(Object o) { - return m.containsValue(o); - } - @Override - public void clear() { - m.clear(); - } - @Override - public Object[] toArray() { return toList(this).toArray(); } - @Override - public T[] toArray(T[] a) { return toList(this).toArray(a); } - } - - static final class EntrySet extends AbstractSet> { - private final ConcurrentNavigableMap m; - EntrySet(ConcurrentNavigableMap map) { - m = map; - } - - @Override - public Iterator> iterator() { - if (m instanceof BTreeMap) - return ((BTreeMap)m).entryIterator(); - else if(m instanceof SubMap) - return ((SubMap)m).entryIterator(); - else - return ((DescendingMap)m).entryIterator(); - } - - @Override - public boolean contains(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry e = (Map.Entry)o; - K1 key = e.getKey(); - if(key == null) return false; - V1 v = m.get(key); - //$DELAY$ - return v != null && v.equals(e.getValue()); - } - @Override - public boolean remove(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry e = (Map.Entry)o; - K1 key = e.getKey(); - if(key == null) return false; - return m.remove(key, - e.getValue()); - } - @Override - public boolean isEmpty() { - return m.isEmpty(); - } - @Override - public int size() { - return m.size(); - } - @Override - public void clear() { - m.clear(); - } - @Override - public boolean equals(Object o) { - if (o == this) - return true; - if (!(o instanceof Set)) - return false; - Collection c = (Collection) o; - try { - return containsAll(c) && c.containsAll(this); - } catch (ClassCastException unused) { - return false; - } catch (NullPointerException unused) { - return false; - } - } - @Override - public Object[] toArray() { return toList(this).toArray(); } - @Override - public T[] toArray(T[] a) { return toList(this).toArray(a); } - } - - - - static protected class SubMap extends AbstractMap implements ConcurrentNavigableMap { - - protected final BTreeMap m; - - protected final K lo; - protected final boolean loInclusive; - - protected final K hi; - protected final boolean hiInclusive; - - public SubMap(BTreeMap m, K lo, boolean loInclusive, K hi, boolean hiInclusive) { - this.m = m; - this.lo = lo; - this.loInclusive = loInclusive; - this.hi = hi; - this.hiInclusive = hiInclusive; - if(lo!=null && hi!=null && m.keySerializer.comparator().compare(lo, hi)>0){ - throw new IllegalArgumentException(); - } - - - } - - -/* ---------------- Map API methods -------------- */ - - @Override - public boolean containsKey(Object key) { - if (key == null) throw new NullPointerException(); - K k = (K)key; - return inBounds(k) && m.containsKey(k); - } - - @Override - public V get(Object key) { - if (key == null) throw new NullPointerException(); - K k = (K)key; - return ((!inBounds(k)) ? null : m.get(k)); - } - - @Override - public V put(K key, V value) { - checkKeyBounds(key); - return m.put(key, value); - } - - @Override - public V remove(Object key) { - if(key==null) - throw new NullPointerException("key null"); - K k = (K)key; - return (!inBounds(k))? null : m.remove(k); - } - - @Override - public int size() { - Iterator i = keyIterator(); - int counter = 0; - while(i.hasNext()){ - counter++; - i.next(); - } - return counter; - } - - @Override - public boolean isEmpty() { - return !keyIterator().hasNext(); - } - - @Override - public boolean containsValue(Object value) { - if(value==null) throw new NullPointerException(); - Iterator i = valueIterator(); - while(i.hasNext()){ - if(value.equals(i.next())) - return true; - } - return false; - } - - @Override - public void clear() { - Iterator i = keyIterator(); - while(i.hasNext()){ - i.next(); - i.remove(); - } - } - - - /* ---------------- ConcurrentMap API methods -------------- */ - - @Override - public V putIfAbsent(K key, V value) { - checkKeyBounds(key); - return m.putIfAbsent(key, value); - } - - @Override - public boolean remove(Object key, Object value) { - K k = (K)key; - return inBounds(k) && m.remove(k, value); - } - - @Override - public boolean replace(K key, V oldValue, V newValue) { - checkKeyBounds(key); - return m.replace(key, oldValue, newValue); - } - - @Override - public V replace(K key, V value) { - checkKeyBounds(key); - return m.replace(key, value); - } - - /* ---------------- SortedMap API methods -------------- */ - - @Override - public Comparator comparator() { - return m.comparator(); - } - - /* ---------------- Relational methods -------------- */ - - @Override - public Map.Entry lowerEntry(K key) { - if(key==null)throw new NullPointerException(); - if(tooLow(key))return null; - - if(tooHigh(key)) - return lastEntry(); - - Entry r = m.lowerEntry(key); - return r!=null && !tooLow(r.getKey()) ? r :null; - } - - @Override - public K lowerKey(K key) { - Entry n = lowerEntry(key); - return (n == null)? null : n.getKey(); - } - - @Override - public Map.Entry floorEntry(K key) { - if(key==null) throw new NullPointerException(); - if(tooLow(key)) return null; - - if(tooHigh(key)){ - return lastEntry(); - } - - Entry ret = m.floorEntry(key); - if(ret!=null && tooLow(ret.getKey())) return null; - return ret; - - } - - @Override - public K floorKey(K key) { - Entry n = floorEntry(key); - return (n == null)? null : n.getKey(); - } - - @Override - public Map.Entry ceilingEntry(K key) { - if(key==null) throw new NullPointerException(); - if(tooHigh(key)) return null; - - if(tooLow(key)){ - return firstEntry(); - } - - Entry ret = m.ceilingEntry(key); - if(ret!=null && tooHigh(ret.getKey())) return null; - return ret; - } - - @Override - public K ceilingKey(K key) { - Entry k = ceilingEntry(key); - return k!=null? k.getKey():null; - } - - @Override - public Entry higherEntry(K key) { - Entry r = m.higherEntry(key); - return r!=null && inBounds(r.getKey()) ? r : null; - } - - @Override - public K higherKey(K key) { - Entry k = higherEntry(key); - return k!=null? k.getKey():null; - } - - - @Override - public K firstKey() { - Entry e = firstEntry(); - if(e==null) throw new NoSuchElementException(); - return e.getKey(); - } - - @Override - public K lastKey() { - Entry e = lastEntry(); - if(e==null) throw new NoSuchElementException(); - return e.getKey(); - } - - - @Override - public Map.Entry firstEntry() { - Entry k = - lo==null ? - m.firstEntry(): - m.findLarger(lo, loInclusive); - return k!=null && inBounds(k.getKey())? k : null; - - } - - @Override - public Map.Entry lastEntry() { - Entry k = - hi==null ? - m.lastEntry(): - m.findSmaller(hi, hiInclusive); - - return k!=null && inBounds(k.getKey())? k : null; - } - - @Override - public Entry pollFirstEntry() { - while(true){ - Entry e = firstEntry(); - if(e==null || remove(e.getKey(),e.getValue())){ - return e; - } - } - } - - @Override - public Entry pollLastEntry() { - while(true){ - Entry e = lastEntry(); - if(e==null || remove(e.getKey(),e.getValue())){ - return e; - } - } - } - - - - - /** - * Utility to create submaps, where given bounds override - * unbounded(null) ones and/or are checked against bounded ones. - */ - private SubMap newSubMap(K fromKey, - boolean fromInclusive, - K toKey, - boolean toInclusive) { - -// if(fromKey!=null && toKey!=null){ -// int comp = m.comparator.compare(fromKey, toKey); -// if((fromInclusive||!toInclusive) && comp==0) -// throw new IllegalArgumentException(); -// } - - if (lo != null) { - if (fromKey == null) { - fromKey = lo; - fromInclusive = loInclusive; - } - else { - int c = m.keySerializer.comparator().compare(fromKey, lo); - if (c < 0 || (c == 0 && !loInclusive && fromInclusive)) - throw new IllegalArgumentException("key out of range"); - } - } - if (hi != null) { - if (toKey == null) { - toKey = hi; - toInclusive = hiInclusive; - } - else { - int c = m.keySerializer.comparator().compare(toKey, hi); - if (c > 0 || (c == 0 && !hiInclusive && toInclusive)) - throw new IllegalArgumentException("key out of range"); - } - } - return new SubMap(m, fromKey, fromInclusive, - toKey, toInclusive); - } - - @Override - public SubMap subMap(K fromKey, - boolean fromInclusive, - K toKey, - boolean toInclusive) { - if (fromKey == null || toKey == null) - throw new NullPointerException(); - return newSubMap(fromKey, fromInclusive, toKey, toInclusive); - } - - @Override - public SubMap headMap(K toKey, - boolean inclusive) { - if (toKey == null) - throw new NullPointerException(); - return newSubMap(null, false, toKey, inclusive); - } - - @Override - public SubMap tailMap(K fromKey, - boolean inclusive) { - if (fromKey == null) - throw new NullPointerException(); - return newSubMap(fromKey, inclusive, null, false); - } - - @Override - public SubMap subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public SubMap headMap(K toKey) { - return headMap(toKey, false); - } - - @Override - public SubMap tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - @Override - public ConcurrentNavigableMap descendingMap() { - return new DescendingMap(m, lo,loInclusive, hi,hiInclusive); - } - - @Override - public NavigableSet navigableKeySet() { - return new KeySet((ConcurrentNavigableMap) this,m.hasValues); - } - - - /* ---------------- Utilities -------------- */ - - - - private boolean tooLow(K key) { - if (lo != null) { - int c = m.keySerializer.comparator().compare(key, lo); - if (c < 0 || (c == 0 && !loInclusive)) - return true; - } - return false; - } - - private boolean tooHigh(K key) { - if (hi != null) { - int c = m.keySerializer.comparator().compare(key, hi); - if (c > 0 || (c == 0 && !hiInclusive)) - return true; - } - return false; - } - - private boolean inBounds(K key) { - return !tooLow(key) && !tooHigh(key); - } - - private void checkKeyBounds(K key) throws IllegalArgumentException { - if (key == null) - throw new NullPointerException(); - if (!inBounds(key)) - throw new IllegalArgumentException("key out of range"); - } - - - - - - @Override - public NavigableSet keySet() { - return new KeySet((ConcurrentNavigableMap) this, m.hasValues); - } - - @Override - public NavigableSet descendingKeySet() { - return new DescendingMap(m,lo,loInclusive, hi, hiInclusive).keySet(); - } - - - - @Override - public Set> entrySet() { - return new EntrySet(this); - } - - - - Iterator keyIterator() { - return new BTreeKeyIterator(m,lo,loInclusive,hi,hiInclusive); - } - - Iterator valueIterator() { - return new BTreeValueIterator(m,lo,loInclusive,hi,hiInclusive); - } - - Iterator> entryIterator() { - return new BTreeEntryIterator(m,lo,loInclusive,hi,hiInclusive); - } - - } - - - static protected class DescendingMap extends AbstractMap implements ConcurrentNavigableMap { - - protected final BTreeMap m; - - protected final K lo; - protected final boolean loInclusive; - - protected final K hi; - protected final boolean hiInclusive; - - public DescendingMap(BTreeMap m, K lo, boolean loInclusive, K hi, boolean hiInclusive) { - this.m = m; - this.lo = lo; - this.loInclusive = loInclusive; - this.hi = hi; - this.hiInclusive = hiInclusive; - if(lo!=null && hi!=null && m.keySerializer.comparator().compare(lo, hi)>0){ - throw new IllegalArgumentException(); - } - - - } - - -/* ---------------- Map API methods -------------- */ - - @Override - public boolean containsKey(Object key) { - if (key == null) throw new NullPointerException(); - K k = (K)key; - return inBounds(k) && m.containsKey(k); - } - - @Override - public V get(Object key) { - if (key == null) throw new NullPointerException(); - K k = (K)key; - return ((!inBounds(k)) ? null : m.get(k)); - } - - @Override - public V put(K key, V value) { - checkKeyBounds(key); - return m.put(key, value); - } - - @Override - public V remove(Object key) { - K k = (K)key; - return (!inBounds(k))? null : m.remove(k); - } - - @Override - public int size() { - Iterator i = keyIterator(); - int counter = 0; - while(i.hasNext()){ - counter++; - i.next(); - } - return counter; - } - - @Override - public boolean isEmpty() { - return !keyIterator().hasNext(); - } - - @Override - public boolean containsValue(Object value) { - if(value==null) throw new NullPointerException(); - Iterator i = valueIterator(); - while(i.hasNext()){ - if(value.equals(i.next())) - return true; - } - return false; - } - - @Override - public void clear() { - Iterator i = keyIterator(); - while(i.hasNext()){ - i.next(); - i.remove(); - } - } - - - /* ---------------- ConcurrentMap API methods -------------- */ - - @Override - public V putIfAbsent(K key, V value) { - checkKeyBounds(key); - return m.putIfAbsent(key, value); - } - - @Override - public boolean remove(Object key, Object value) { - K k = (K)key; - return inBounds(k) && m.remove(k, value); - } - - @Override - public boolean replace(K key, V oldValue, V newValue) { - checkKeyBounds(key); - return m.replace(key, oldValue, newValue); - } - - @Override - public V replace(K key, V value) { - checkKeyBounds(key); - return m.replace(key, value); - } - - /* ---------------- SortedMap API methods -------------- */ - - @Override - public Comparator comparator() { - return m.comparator(); - } - - /* ---------------- Relational methods -------------- */ - - @Override - public Map.Entry higherEntry(K key) { - if(key==null)throw new NullPointerException(); - if(tooLow(key))return null; - - if(tooHigh(key)) - return firstEntry(); - - Entry r = m.lowerEntry(key); - return r!=null && !tooLow(r.getKey()) ? r :null; - } - - @Override - public K lowerKey(K key) { - Entry n = lowerEntry(key); - return (n == null)? null : n.getKey(); - } - - @Override - public Map.Entry ceilingEntry(K key) { - if(key==null) throw new NullPointerException(); - if(tooLow(key)) return null; - - if(tooHigh(key)){ - return firstEntry(); - } - - Entry ret = m.floorEntry(key); - if(ret!=null && tooLow(ret.getKey())) return null; - return ret; - - } - - @Override - public K floorKey(K key) { - Entry n = floorEntry(key); - return (n == null)? null : n.getKey(); - } - - @Override - public Map.Entry floorEntry(K key) { - if(key==null) throw new NullPointerException(); - if(tooHigh(key)) return null; - - if(tooLow(key)){ - return lastEntry(); - } - - Entry ret = m.ceilingEntry(key); - if(ret!=null && tooHigh(ret.getKey())) return null; - return ret; - } - - @Override - public K ceilingKey(K key) { - Entry k = ceilingEntry(key); - return k!=null? k.getKey():null; - } - - @Override - public Entry lowerEntry(K key) { - Entry r = m.higherEntry(key); - return r!=null && inBounds(r.getKey()) ? r : null; - } - - @Override - public K higherKey(K key) { - Entry k = higherEntry(key); - return k!=null? k.getKey():null; - } - - - @Override - public K firstKey() { - Entry e = firstEntry(); - if(e==null) throw new NoSuchElementException(); - return e.getKey(); - } - - @Override - public K lastKey() { - Entry e = lastEntry(); - if(e==null) throw new NoSuchElementException(); - return e.getKey(); - } - - - @Override - public Map.Entry lastEntry() { - Entry k = - lo==null ? - m.firstEntry(): - m.findLarger(lo, loInclusive); - return k!=null && inBounds(k.getKey())? k : null; - - } - - @Override - public Map.Entry firstEntry() { - Entry k = - hi==null ? - m.lastEntry(): - m.findSmaller(hi, hiInclusive); - - return k!=null && inBounds(k.getKey())? k : null; - } - - @Override - public Entry pollFirstEntry() { - while(true){ - Entry e = firstEntry(); - if(e==null || remove(e.getKey(),e.getValue())){ - return e; - } - } - } - - @Override - public Entry pollLastEntry() { - while(true){ - Entry e = lastEntry(); - if(e==null || remove(e.getKey(),e.getValue())){ - return e; - } - } - } - - - - - /** - * Utility to create submaps, where given bounds override - * unbounded(null) ones and/or are checked against bounded ones. - */ - private DescendingMap newSubMap( - K toKey, - boolean toInclusive, - K fromKey, - boolean fromInclusive) { - -// if(fromKey!=null && toKey!=null){ -// int comp = m.comparator.compare(fromKey, toKey); -// if((fromInclusive||!toInclusive) && comp==0) -// throw new IllegalArgumentException(); -// } - - if (lo != null) { - if (fromKey == null) { - fromKey = lo; - fromInclusive = loInclusive; - } - else { - int c = m.keySerializer.comparator().compare(fromKey, lo); - if (c < 0 || (c == 0 && !loInclusive && fromInclusive)) - throw new IllegalArgumentException("key out of range"); - } - } - if (hi != null) { - if (toKey == null) { - toKey = hi; - toInclusive = hiInclusive; - } - else { - int c = m.keySerializer.comparator().compare(toKey, hi); - if (c > 0 || (c == 0 && !hiInclusive && toInclusive)) - throw new IllegalArgumentException("key out of range"); - } - } - return new DescendingMap(m, fromKey, fromInclusive, - toKey, toInclusive); - } - - @Override - public DescendingMap subMap(K fromKey, - boolean fromInclusive, - K toKey, - boolean toInclusive) { - if (fromKey == null || toKey == null) - throw new NullPointerException(); - return newSubMap(fromKey, fromInclusive, toKey, toInclusive); - } - - @Override - public DescendingMap headMap(K toKey, - boolean inclusive) { - if (toKey == null) - throw new NullPointerException(); - return newSubMap(null, false, toKey, inclusive); - } - - @Override - public DescendingMap tailMap(K fromKey, - boolean inclusive) { - if (fromKey == null) - throw new NullPointerException(); - return newSubMap(fromKey, inclusive, null, false); - } - - @Override - public DescendingMap subMap(K fromKey, K toKey) { - return subMap(fromKey, true, toKey, false); - } - - @Override - public DescendingMap headMap(K toKey) { - return headMap(toKey, false); - } - - @Override - public DescendingMap tailMap(K fromKey) { - return tailMap(fromKey, true); - } - - @Override - public ConcurrentNavigableMap descendingMap() { - if(lo==null && hi==null) return m; - return m.subMap(lo,loInclusive,hi,hiInclusive); - } - - @Override - public NavigableSet navigableKeySet() { - return new KeySet((ConcurrentNavigableMap) this,m.hasValues); - } - - - /* ---------------- Utilities -------------- */ - - - - private boolean tooLow(K key) { - if (lo != null) { - int c = m.keySerializer.comparator().compare(key, lo); - if (c < 0 || (c == 0 && !loInclusive)) - return true; - } - return false; - } - - private boolean tooHigh(K key) { - if (hi != null) { - int c = m.keySerializer.comparator().compare(key, hi); - if (c > 0 || (c == 0 && !hiInclusive)) - return true; - } - return false; - } - - private boolean inBounds(K key) { - return !tooLow(key) && !tooHigh(key); - } - - private void checkKeyBounds(K key) throws IllegalArgumentException { - if (key == null) - throw new NullPointerException(); - if (!inBounds(key)) - throw new IllegalArgumentException("key out of range"); - } - - - - - - @Override - public NavigableSet keySet() { - return new KeySet((ConcurrentNavigableMap) this, m.hasValues); - } - - @Override - public NavigableSet descendingKeySet() { - return new KeySet((ConcurrentNavigableMap) descendingMap(), m.hasValues); - } - - - - @Override - public Set> entrySet() { - return new EntrySet(this); - } - - - /* - * ITERATORS - */ - - abstract class Iter implements Iterator { - Entry current = DescendingMap.this.firstEntry(); - Entry last = null; - - - @Override - public boolean hasNext() { - return current!=null; - } - - - public void advance() { - if(current==null) throw new NoSuchElementException(); - last = current; - current = DescendingMap.this.higherEntry(current.getKey()); - } - - @Override - public void remove() { - if(last==null) throw new IllegalStateException(); - DescendingMap.this.remove(last.getKey()); - last = null; - } - - } - Iterator keyIterator() { - return new Iter() { - @Override - public K next() { - advance(); - return last.getKey(); - } - }; - } - - Iterator valueIterator() { - return new Iter() { - - @Override - public V next() { - advance(); - return last.getValue(); - } - }; - } - - Iterator> entryIterator() { - return new Iter>() { - @Override - public Entry next() { - advance(); - return last; - } - }; - } - - - } - - - /** - * Make readonly snapshot view of current Map. Snapshot is immutable and not affected by modifications made by other threads. - * Useful if you need consistent view on Map. - * - * Maintaining snapshot have some overhead, underlying Engine is closed after Map view is GCed. - * Please make sure to release reference to this Map view, so snapshot view can be garbage collected. - * - * @return snapshot - */ - public NavigableMap snapshot(){ - Engine snapshot = TxEngine.createSnapshotFor(engine); - - return new BTreeMap(snapshot, rootRecidRef, maxNodeSize, valsOutsideNodes, - counter==null?0L:counter.recid, - keySerializer, valueSerializer, numberOfNodeMetas); - } - - - - protected final Object modListenersLock = new Object(); - protected Bind.MapListener[] modListeners = new Bind.MapListener[0]; - - @Override - public void modificationListenerAdd(Bind.MapListener listener) { - synchronized (modListenersLock){ - Bind.MapListener[] modListeners2 = - Arrays.copyOf(modListeners,modListeners.length+1); - modListeners2[modListeners2.length-1] = listener; - modListeners = modListeners2; - } - - } - - @Override - public void modificationListenerRemove(Bind.MapListener listener) { - synchronized (modListenersLock){ - for(int i=0;i[] modListeners2 = modListeners; - for(Bind.MapListener listener:modListeners2){ - if(listener!=null) - listener.update(key, oldValue, newValue); - } - } - - - public Engine getEngine(){ - return engine; - } - - - public void printTreeStructure() { - final long rootRecid = engine.get(rootRecidRef, Serializer.LONG); - printRecur(this, rootRecid, ""); - } - - private static void printRecur(BTreeMap m, long recid, String s) { - BTreeMap.BNode n = (BTreeMap.BNode) m.engine.get(recid, m.nodeSerializer); - System.out.println(s+recid+"-"+n); - if(!n.isLeaf()){ - for(int i=0;i locks){ - LongMap.LongMapIterator i = locks.longMapIterator(); - Thread t =null; - while(i.moveToNext()){ - if(t==null) - t = Thread.currentThread(); - if(i.value()==t){ - throw new AssertionError("Node "+i.key()+" is still locked"); - } - } - } - - - protected static void unlock(LongConcurrentHashMap locks,final long recid) { - final Thread t = locks.remove(recid); - if(CC.PARANOID && ! (t==Thread.currentThread())) - throw new AssertionError("unlocked wrong thread"); - } - - protected static void unlockAll(LongConcurrentHashMap locks) { - final Thread t = Thread.currentThread(); - LongMap.LongMapIterator iter = locks.longMapIterator(); - while(iter.moveToNext()) - if(iter.value()==t) - iter.remove(); - } - - - protected static void lock(LongConcurrentHashMap locks, long recid){ - //feel free to rewrite, if you know better (more efficient) way - - final Thread currentThread = Thread.currentThread(); - //check node is not already locked by this thread - if(CC.PARANOID && ! (locks.get(recid)!= currentThread)) - throw new AssertionError("node already locked by current thread: "+recid); - - while(locks.putIfAbsent(recid, currentThread) != null){ - LockSupport.parkNanos(10); - } - } - - - public void checkStructure(){ - LongHashMap recids = new LongHashMap(); - final long recid = engine.get(rootRecidRef, Serializer.LONG); - - checkNodeRecur(recid,recids); - - } - - private void checkNodeRecur(long rootRecid, LongHashMap recids) { - BNode n = engine.get(rootRecid, nodeSerializer); - n.checkStructure(keySerializer); - - if(recids.get(rootRecid)!=null){ - throw new AssertionError("Duplicate recid: "+rootRecid); - } - recids.put(rootRecid,this); - - if(n.next()!=0L && recids.get(n.next())==null){ - throw new AssertionError("Next link was not found: "+n); - } - if(n.next()==rootRecid){ - throw new AssertionError("Recursive next: "+n); - } - if(!n.isLeaf()){ - long[] child = n.child(); - for(int i=child.length-1; i>=0; i--){ - long recid = child[i]; - if(recid==rootRecid){ - throw new AssertionError("Recursive recid: "+n); - } - - if(recid==0 || recid==n.next()){ - continue; - } - checkNodeRecur(recid, recids);; - - } - } - - } - - -} diff --git a/src/main/java/org/mapdb/Bind.java b/src/main/java/org/mapdb/Bind.java deleted file mode 100644 index ab0b9fd05..000000000 --- a/src/main/java/org/mapdb/Bind.java +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; - -/** - * Binding is simple yet powerful way to keep secondary collection synchronized with primary collection. - * Primary collection provides notification on updates and secondary collection is modified accordingly. - * This way MapDB provides secondary indexes, values and keys. It also supports less usual scenarios such - * as histograms, inverse lookup index (on maps), group counters and so on. - * - * There are two things to keep on mind when using binding: - * - * * Binding is not persistent, so it needs to be restored every time store is reopened. - * If you modify primary collection before binding is restored, secondary collection does not get updated and becomes - * inconsistent. - * - * * If secondary collection is empty, binding will recreate its content based on primary collection. - * If there is even single item on secondary collection, binding assumes it is consistent and leaves it as its. - * - * Any thread-safe collection can be used as secondary (not just collections provided by MapDB). - * This gives great flexibility for modeling - * and scaling your data. For example primary data can be stored in durable DB with transactions and large secondary - * indexes may be stored in other faster non-durable DB. Or primary collection may be stored on disk and smaller - * secondary index (such as category counters) can be stored in memory for faster lookups. Also you may use - * ordinary {@code java.util.*} collections (if they are thread safe) to get additional speed. - * - * There are many [code examples](https://github.com/jankotek/MapDB/tree/master/src/test/java/examples) - * how Collection Binding can be used. - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * - * @author Jan Kotek - */ -public final class Bind { - - private Bind(){} - - - - /** - * Listener called when {@code Map} is modified. - * @param key type in map - * @param value type in map - */ - public interface MapListener{ - /** - * Callback method called after {@code Map} was modified. - * It is called on insert, update or delete. - * - * MapDB collections do not support null keys or values. - * Null parameter may be than used to indicate operation: - * - * - * - * @param key key in map - * @param oldVal old value in map (if any, null on inserts) - * @param newVal new value in map (if any, null on deletes) - */ - void update(K key, V oldVal, V newVal); - } - - /** - * Primary Maps must provide notifications when it is modified. - * So Primary Maps must implement this interface to allow registering callback listeners. - * - * @param key type in map - * @param value type in map - */ - public interface MapWithModificationListener extends Map { - /** - * Add new modification listener notified when Map has been updated - * @param listener callback interface notified when map changes - */ - public void modificationListenerAdd(MapListener listener); - - /** - * Remove registered notification listener - * - * @param listener callback interface notified when map changes - */ - public void modificationListenerRemove(MapListener listener); - - - /** - * - * @return size of map, but in 64bit long which does not overflow at 2e9 items. - */ - public long sizeLong(); - } - - /** - * Binds {@link Atomic.Long} to Primary Map so the Atomic.Long contains size of Map. - * {@code Atomic.Long} is incremented on each insert and decremented on each entry removal. - * MapDB collections usually do not keep their size, but require complete traversal to count items. - * - * If {@code Atomic.Long} has zero value, it will be updated with value from {@code map.size()} and than - * bind to map. - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * - * NOTE: {@link BTreeMap} and {@link HTreeMap} already supports this directly as optional parameter named {@code counter}. - * In that case all calls to {@code Map.size()} are forwarded to underlying counter. Check parameters at - * {@link DB#createHashMap(String)} and - * {@link DB#createTreeMap(String)} - * - * - * @param map primary map whose size needs to be tracked - * @param sizeCounter number updated when Map Entry is added or removed. - */ - public static void size(MapWithModificationListener map, final Atomic.Long sizeCounter){ - //set initial value first if necessary - //$DELAY$ - if(sizeCounter.get() == 0){ - //$DELAY$ - long size = map.sizeLong(); - if(sizeCounter.get()!=size) { - //$DELAY$ - sizeCounter.set(size); - //$DELAY$ - } - } - - map.modificationListenerAdd(new MapListener() { - @Override - public void update(K key, V oldVal, V newVal) { - //$DELAY$ - if (oldVal == null && newVal != null) { - //$DELAY$ - sizeCounter.incrementAndGet(); - } else if (oldVal != null && newVal == null) { - //$DELAY$ - sizeCounter.decrementAndGet(); - } - //$DELAY$ - - //update does not change collection size - } - }); - } - - /** - * Binds Secondary Map so that it contains Key from Primary Map and custom Value. - * Secondary Value is updated every time Primary Map is modified. - * - * If Secondary Map is empty its content will be recreated from Primary Map. - * This binding is not persistent. You need to restore it every time store is reopened. - * - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * Type params: - * - * @param - key type in primary and Secondary Map - * @param - value type in Primary Map - * @param - value type in Secondary Map - * - * @param map Primary Map - * @param secondary Secondary Map with custom - * @param fun function which calculates secondary value from primary key and value - */ - public static void secondaryValue(MapWithModificationListener map, - final Map secondary, - final Fun.Function2 fun){ - //$DELAY$ - //fill if empty - if(secondary.isEmpty()){ - //$DELAY$ - for(Map.Entry e:map.entrySet()) - secondary.put(e.getKey(), fun.run(e.getKey(),e.getValue())); - } - //$DELAY$ - //hook listener - map.modificationListenerAdd(new MapListener() { - @Override - public void update(K key, V oldVal, V newVal) { - //$DELAY$ - if (newVal == null) { - //removal - secondary.remove(key); - //$DELAY$ - } else { - //$DELAY$ - secondary.put(key, fun.run(key, newVal)); - } - //$DELAY$ - } - }); - } - - /** - * Binds Secondary Map so that it contains Key from Primary Map and custom Value. - * Secondary Value is updated every time Primary Map is modified. - * - * If Secondary Map is empty its content will be recreated from Primary Map. - * This binding is not persistent. You need to restore it every time store is reopened. - * - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * Type params: - * - * @param - key type in primary and Secondary Map - * @param - value type in Primary Map - * @param - value type in Secondary Map - * . - * @param map Primary Map - * @param secondary Secondary Map with custom - * @param fun function which calculates secondary values from primary key and value - */ - public static void secondaryValues(MapWithModificationListener map, - final Set secondary, - final Fun.Function2 fun){ - //$DELAY$ - //fill if empty - if(secondary.isEmpty()){ - //$DELAY$ - for(Map.Entry e:map.entrySet()){ - V2[] v = fun.run(e.getKey(),e.getValue()); - //$DELAY$ - if(v!=null) { - for (V2 v2 : v) { - //$DELAY$ - secondary.add(new Object[]{e.getKey(), v2}); - //$DELAY$ - } - } - } - } - - //$DELAY$ - - //hook listener - map.modificationListenerAdd(new MapListener() { - @Override - public void update(K key, V oldVal, V newVal) { - //$DELAY$ - if (newVal == null) { - //$DELAY$ - //removal - V2[] v = fun.run(key, oldVal); - if (v != null) { - for (V2 v2 : v) { - //$DELAY$ - secondary.remove(new Object[]{key, v2}); - } - } - } else if (oldVal == null) { - //$DELAY$ - //insert - V2[] v = fun.run(key, newVal); - if (v != null) { - for (V2 v2 : v) { - //$DELAY$ - secondary.add(new Object[]{key, v2}); - } - } - } else { - //$DELAY$ - //update, must remove old key and insert new - V2[] oldv = fun.run(key, oldVal); - V2[] newv = fun.run(key, newVal); - if (oldv == null) { - //$DELAY$ - //insert new - if (newv != null) { - for (V2 v : newv) { - //$DELAY$ - secondary.add(new Object[]{key, v}); - } - } - return; - } - if (newv == null) { - //remove old - for (V2 v : oldv) { - //$DELAY$ - secondary.remove(new Object[]{key, v}); - } - return; - } - - Set hashes = new HashSet(); - Collections.addAll(hashes, oldv); - //$DELAY$ - //add new non existing items - for (V2 v : newv) { - if (!hashes.contains(v)) { - secondary.add(new Object[]{key, v}); - } - } - //remove items which are in old, but not in new - for (V2 v : newv) { - //$DELAY$ - hashes.remove(v); - } - for (V2 v : hashes) { - //$DELAY$ - secondary.remove(new Object[]{key, v}); - } - } - } - }); - } - - - /** - * Binds Secondary Set so it contains Secondary Key (Index). Usefull if you need - * to lookup Keys from Primary Map by custom criteria. Other use is for reverse lookup - * - * To lookup keys in Secondary Set use {@link Fun#filter(java.util.NavigableSet, Object[])} - * - * If Secondary Set is empty its content will be recreated from Primary Map. - * This binding is not persistent. You need to restore it every time store is reopened. - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * Type params: - * - * @param - Key in Primary Map - * @param - Value in Primary Map - * @param - Secondary - * - * @param map primary map - * @param secondary secondary set - * @param fun function which calculates Secondary Key from Primary Key and Value - */ - public static void secondaryKey(MapWithModificationListener map, - final Set secondary, - final Fun.Function2 fun){ - //$DELAY$ - //fill if empty - if(secondary.isEmpty()){ - for(Map.Entry e:map.entrySet()){ - //$DELAY$ - secondary.add(new Object[]{fun.run(e.getKey(),e.getValue()), e.getKey()}); - } - } - //hook listener - map.modificationListenerAdd(new MapListener() { - @Override - public void update(K key, V oldVal, V newVal) { - //$DELAY$ - if (newVal == null) { - //removal - //$DELAY$ - secondary.remove(new Object[]{fun.run(key, oldVal), key}); - } else if (oldVal == null) { - //insert - //$DELAY$ - secondary.add(new Object[]{fun.run(key, newVal), key}); - } else { - //update, must remove old key and insert new - //$DELAY$ - K2 oldKey = fun.run(key, oldVal); - K2 newKey = fun.run(key, newVal); - if (oldKey == newKey || oldKey.equals(newKey)) return; - //$DELAY$ - secondary.remove(new Object[]{oldKey, key}); - //$DELAY$ - secondary.add(new Object[]{newKey, key}); - //$DELAY$ - } - } - }); - } - - /** - * Binds Secondary Set so it contains Secondary Key (Index). Usefull if you need - * to lookup Keys from Primary Map by custom criteria. Other use is for reverse lookup - * - * If Secondary Set is empty its content will be recreated from Primary Map. - * This binding is not persistent. You need to restore it every time store is reopened. - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * Type params: - * - * @param - Key in Primary Map - * @param - Value in Primary Map - * @param - Secondary - * - * @param map primary map - * @param secondary secondary set - * @param fun function which calculates Secondary Key from Primary Key and Value - */ - public static void secondaryKey(MapWithModificationListener map, - final Map secondary, - final Fun.Function2 fun){ - //$DELAY$ - //fill if empty - if(secondary.isEmpty()){ - for(Map.Entry e:map.entrySet()){ - //$DELAY$ - secondary.put(fun.run(e.getKey(), e.getValue()), e.getKey()); - } - } - //$DELAY$ - //hook listener - map.modificationListenerAdd(new MapListener() { - @Override - public void update(K key, V oldVal, V newVal) { - //$DELAY$ - if (newVal == null) { - //removal - secondary.remove(fun.run(key, oldVal)); - } else if (oldVal == null) { - //insert - secondary.put(fun.run(key, newVal), key); - } else { - //$DELAY$ - //update, must remove old key and insert new - K2 oldKey = fun.run(key, oldVal); - K2 newKey = fun.run(key, newVal); - if (oldKey == newKey || oldKey.equals(newKey)) return; - //$DELAY$ - secondary.remove(oldKey); - //$DELAY$ - secondary.put(newKey, key); - } - } - }); - } - /** - * Binds Secondary Set so it contains Secondary Key (Index). Useful if you need - * to lookup Keys from Primary Map by custom criteria. Other use is for reverse lookup - * - * To lookup keys in Secondary Set use {@link Fun#filter(java.util.NavigableSet, Object[])}} - * - * - * If Secondary Set is empty its content will be recreated from Primary Map. - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * - * Type params: - * - * @param - Key in Primary Map - * @param - Value in Primary Map - * @param - Secondary - * - * @param map primary map - * @param secondary secondary set - * @param fun function which calculates Secondary Keys from Primary Key and Value - */ - public static void secondaryKeys(MapWithModificationListener map, - final Set secondary, - final Fun.Function2 fun){ - //$DELAY$ - //fill if empty - if(secondary.isEmpty()){ - for(Map.Entry e:map.entrySet()){ - //$DELAY$ - K2[] k2 = fun.run(e.getKey(), e.getValue()); - if(k2 != null) { - for (K2 k22 : k2) { - //$DELAY$ - secondary.add(new Object[]{k22, e.getKey()}); - } - } - } - } - //$DELAY$ - //hook listener - map.modificationListenerAdd(new MapListener() { - @Override - public void update(K key, V oldVal, V newVal) { - //$DELAY$ - if (newVal == null) { - //$DELAY$ - //removal - K2[] k2 = fun.run(key, oldVal); - if (k2 != null) { - for (K2 k22 : k2) { - //$DELAY$ - secondary.remove(new Object[]{k22, key}); - } - } - } else if (oldVal == null) { - //$DELAY$ - //insert - K2[] k2 = fun.run(key, newVal); - //$DELAY$ - if (k2 != null) { - for (K2 k22 : k2) { - //$DELAY$ - secondary.add(new Object[]{k22, key}); - } - } - } else { - //$DELAY$ - //update, must remove old key and insert new - K2[] oldk = fun.run(key, oldVal); - K2[] newk = fun.run(key, newVal); - if (oldk == null) { - //insert new - if (newk != null) { - for (K2 k22 : newk) { - //$DELAY$ - secondary.add(new Object[]{k22, key}); - } - } - return; - } - if (newk == null) { - //remove old - for (K2 k22 : oldk) { - //$DELAY$ - secondary.remove(new Object[]{k22, key}); - } - return; - } - - //$DELAY$ - Set hashes = new HashSet(); - //$DELAY$ - Collections.addAll(hashes, oldk); - - //add new non existing items - for (K2 k2 : newk) { - //$DELAY$ - if (!hashes.contains(k2)) { - //$DELAY$ - secondary.add(new Object[]{k2, key}); - } - } - //remove items which are in old, but not in new - for (K2 k2 : newk) { - //$DELAY$ - hashes.remove(k2); - } - for (K2 k2 : hashes) { - //$DELAY$ - secondary.remove(new Object[]{k2, key}); - } - } - } - }); - } - - /** - * Binds Secondary Set so it contains inverse mapping to Primary Map: Primary Value will become Secondary Key. - * This is useful for creating bi-directional Maps. - * - * To lookup keys in Secondary Set use {@link Fun#filter(java.util.NavigableSet, Object[])} - * - * If Secondary Set is empty its content will be recreated from Primary Map. - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * Type params: - * - * @param - Key in Primary Map and Second Value in Secondary Set - * @param - Value in Primary Map and Primary Value in Secondary Set - * - * @param primary Primary Map for which inverse mapping will be created - * @param inverse Secondary Set which will contain inverse mapping - */ - public static void mapInverse(MapWithModificationListener primary, - Set inverse) { - Bind.secondaryKey(primary,inverse, new Fun.Function2(){ - @Override public V run(K key, V value) { - return value; - } - }); - } - - /** - * Binds Secondary Set so it contains inverse mapping to Primary Map: Primary Value will become Secondary Key. - * This is useful for creating bi-directional Maps. - * - * In this case some data may be lost, if there are duplicated primary values. - * It is recommended to use multimap: {@code NavigableSet>} which - * handles value duplicities. Use {@link Bind#mapInverse(org.mapdb.Bind.MapWithModificationListener, java.util.Map)} - * - * If Secondary Set is empty its content will be recreated from Primary Map. - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * Type params: - * - * @param - Key in Primary Map and Second Value in Secondary Set - * @param - Value in Primary Map and Primary Value in Secondary Set - * - * @param primary Primary Map for which inverse mapping will be created - * @param inverse Secondary Set which will contain inverse mapping - */ - public static void mapInverse(MapWithModificationListener primary, - Map inverse) { - Bind.secondaryKey(primary,inverse, new Fun.Function2(){ - @Override public V run(K key, V value) { - return value; - } - }); - } - - - - - - - - /** - * Binds Secondary Map so it it creates [histogram](http://en.wikipedia.org/wiki/Histogram) from - * data in Primary Map. Histogram keeps count how many items are in each category. - * This method takes function which defines in what category each Primary Map entry is in. - * - * - * If Secondary Map is empty its content will be recreated from Primary Map. - * - * NOTE: Binding just installs Modification Listener on primary collection. Binding itself is not persistent - * and has to be restored after primary collection is loaded. Data contained in secondary collection are persistent. - * - * - * Type params: - * - * @param - Key type in primary map - * @param - Value type in primary map - * @param - Category type - * - * @param primary Primary Map to create histogram for - * @param histogram Secondary Map to create histogram for, key is Category, value is number of items in category - * @param entryToCategory returns Category in which entry from Primary Map belongs to. - */ - public static void histogram(MapWithModificationListener primary, final ConcurrentMap histogram, - final Fun.Function2 entryToCategory){ - - //$DELAY$ - MapListener listener = new MapListener() { - @Override public void update(K key, V oldVal, V newVal) { - //$DELAY$ - if(newVal == null){ - //$DELAY$ - //removal - C category = entryToCategory.run(key,oldVal); - incrementHistogram(category, -1); - }else if(oldVal==null){ - //$DELAY$ - //insert - C category = entryToCategory.run(key,newVal); - incrementHistogram(category, 1); - }else{ - //$DELAY$ - //update, must remove old key and insert new - C oldCat = entryToCategory.run(key, oldVal); - C newCat = entryToCategory.run(key, newVal); - //$DELAY$ - if(oldCat == newCat || oldCat.equals(newCat)) return; - incrementHistogram(oldCat,-1); - incrementHistogram(oldCat,1); - } - - } - - /** atomically update counter in histogram*/ - private void incrementHistogram(C category, long i) { - //$DELAY$ - for(;;){ - //$DELAY$ - Long oldCount = histogram.get(category); - if(oldCount == null){ - //$DELAY$ - //insert new count - if(histogram.putIfAbsent(category,i) == null) { - //$DELAY$ - return; - } - }else{ - //increase existing count - //$DELAY$ - Long newCount = oldCount+i; - if(histogram.replace(category,oldCount, newCount)) { - //$DELAY$ - return; - } - } - } - } - }; - - primary.modificationListenerAdd(listener); - } -} diff --git a/src/main/java/org/mapdb/CC.java b/src/main/java/org/mapdb/CC.java index ccfa637fb..3f9225baf 100644 --- a/src/main/java/org/mapdb/CC.java +++ b/src/main/java/org/mapdb/CC.java @@ -1,104 +1,9 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - package org.mapdb; -/** - * Compiler Configuration. There are some static final boolean fields, which describe features MapDB was compiled with. - *

- * MapDB can be compiled with/without some features. For example fine logging is useful for debuging, - * but should not be present in production version. Java does not have preprocessor so - * we use Dead code elimination to achieve it. - *

- * Typical usage: - *

{@code
- *     if(CC.PARANOID && arg.calculateSize()!=33){  //calculateSize may take long time
- *         throw new IllegalArgumentException("wrong size");
- *     }
- * }
- * - * @author Jan Kotek - */ +//TODO name conflict with 3.0, remove this class public interface CC { - - /** - * Compile with more assertions and verifications. - * For example HashMap may check if keys implements hash function correctly. - * This may slow down MapDB thousands times - */ - boolean PARANOID = false; - - /** - * Compile-in detailed log messages from store. - */ + boolean PARANOID = false; + boolean ASSERT = true; + //TODO move to preprocessor boolean LOG_STORE = false; - - /** - * Compile-in detailed log messages from Engine Wrappers - */ - boolean LOG_EWRAP = false; - -// /** -// * Log lock/unlock events. Useful to diagnose deadlocks -// */ -// boolean LOG_LOCKS = false; -// -// /** -// * If true MapDB will display warnings if user is using MapDB API wrong way. -// */ -// boolean LOG_HINTS = true; - - - - /** - * Compile-in detailed log messages from HTreeMap. - */ - boolean LOG_HTREEMAP = false; - - - int ASYNC_WRITE_FLUSH_DELAY = 100; - int ASYNC_WRITE_QUEUE_SIZE = 32000; - - int ASYNC_RECID_PREALLOC_QUEUE_SIZE = 128; - - /** - * Concurrency level. Should be greater than number of threads accessing - * MapDB concurrently. On other side larger number consumes more memory - *

- * This number must be power of two: `CONCURRENCY = 2^N` - */ - int CONCURRENCY = 128; - - -// int BTREE_DEFAULT_MAX_NODE_SIZE = 32; - - - int DEFAULT_CACHE_SIZE = 1024 * 32; - - String DEFAULT_CACHE = DBMaker.Keys.cache_hashTable; - - int DEFAULT_FREE_SPACE_RECLAIM_Q = 5; - - /** controls if locks used in MapDB are fair */ - boolean FAIR_LOCKS = false; - - - int VOLUME_SLICE_SHIFT = 20; // 1 MB - - @Deprecated - int VOLUME_CHUNK_SHIFT = VOLUME_SLICE_SHIFT; } - diff --git a/src/main/java/org/mapdb/Caches.java b/src/main/java/org/mapdb/Caches.java deleted file mode 100644 index 38451c17b..000000000 --- a/src/main/java/org/mapdb/Caches.java +++ /dev/null @@ -1,828 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ -package org.mapdb; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.util.Arrays; -import java.util.Random; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.logging.Level; - -/** - * Contains various instance cache implementations - */ -public final class Caches { - - private Caches(){} - - - /** - * Least Recently Used cache. - * If cache is full it removes less used items to make a space - */ - public static class LRU extends EngineWrapper { - - protected LongMap cache; - - protected final Fun.RecordCondition condition; - - protected final ReentrantLock[] locks; - - - public LRU(Engine engine, int cacheSize, Fun.RecordCondition condition) { - this(engine, new LongConcurrentLRUMap(cacheSize, (int) (cacheSize*0.8)), condition); - } - - public LRU(Engine engine, LongMap cache, Fun.RecordCondition condition){ - super(engine); - - locks = new ReentrantLock[CC.CONCURRENCY]; - for(int i=0;i long put(A value, Serializer serializer) { - //$DELAY$ - long recid = super.put(value, serializer); - - if(!condition.run(recid, value, serializer)) - return recid; - //$DELAY$ - final LongMap cache2 = checkClosed(cache); - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - try{ - //$DELAY$ - cache2.put(recid, value); - }finally { - - lock.unlock(); - - } - //$DELAY$ - return recid; - } - - @SuppressWarnings("unchecked") - @Override - public A get(long recid, Serializer serializer) { - final LongMap cache2 = checkClosed(cache); - //$DELAY$ - Object ret = cache2.get(recid); - if(ret!=null) - return (A) ret; - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - //$DELAY$ - ret = super.get(recid, serializer); - if(ret!=null && condition.run(recid, ret, serializer)) { - //$DELAY$ - cache2.put(recid, ret); - } - //$DELAY$ - return (A) ret; - }finally { - lock.unlock(); - } - } - - @Override - public void update(long recid, A value, Serializer serializer) { - //$DELAY$ - if(!condition.run(recid, value, serializer)){ - //$DELAY$ - super.update(recid,value,serializer); - return; - } - - - final LongMap cache2 = checkClosed(cache); - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - cache2.put(recid, value); - //$DELAY$ - super.update(recid, value, serializer); - }finally { - lock.unlock(); - } - //$DELAY$ - } - - @Override - public void delete(long recid, Serializer serializer){ - final LongMap cache2 = checkClosed(cache); - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - try{ - //$DELAY$ - cache2.remove(recid); - //$DELAY$ - super.delete(recid,serializer); - }finally { - lock.unlock(); - } - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - if(!condition.run(recid, newValue, serializer)){ - //$DELAY$ - return super.compareAndSwap(recid,expectedOldValue,newValue,serializer); - } - - Engine engine = getWrappedEngine(); - LongMap cache2 = checkClosed(cache); - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - Object oldValue = cache2.get(recid); - //$DELAY$ - if(oldValue == expectedOldValue || (oldValue!=null&&oldValue.equals(expectedOldValue))){ - //found matching entry in cache, so just update and return true - cache2.put(recid, newValue); - //$DELAY$ - engine.update(recid, newValue, serializer); - //$DELAY$ - return true; - }else{ - //$DELAY$ - boolean ret = engine.compareAndSwap(recid, expectedOldValue, newValue, serializer); - //$DELAY$ - if(ret) cache2.put(recid, newValue); - //$DELAY$ - return ret; - } - }finally { - lock.unlock(); - } - //$DELAY$ - } - - - @Override - public void close() { - cache = null; - super.close(); - } - - @Override - public void rollback() { - //TODO locking here? - checkClosed(cache).clear(); - super.rollback(); - } - - @Override - public void clearCache() { - cache.clear(); - super.clearCache(); - } - } - - /** - * Fixed size cache which uses hash table. - * Is thread-safe and requires only minimal locking. - * Items are randomly removed and replaced by hash collisions. - *

- * This is simple, concurrent, small-overhead, random cache. - * - * @author Jan Kotek - */ - public static class HashTable extends EngineWrapper implements Engine { - - - protected final ReentrantLock[] locks; - - protected HashItem[] items; - protected final int cacheMaxSize; - protected final int cacheMaxSizeMask; - - /** - * Salt added to keys before hashing, so it is harder to trigger hash collision attack. - */ - protected final long hashSalt = new Random().nextLong(); - - protected final Fun.RecordCondition condition; - - private static final class HashItem { - final long key; - final Object val; - - private HashItem(long key, Object val) { - this.key = key; - this.val = val; - } - } - - - public HashTable(Engine engine, int cacheMaxSize, Fun.RecordCondition condition) { - super(engine); - locks = new ReentrantLock[CC.CONCURRENCY]; - for(int i=0;i long put(A value, Serializer serializer) { - //$DELAY$ - final long recid = getWrappedEngine().put(value, serializer); - HashItem[] items2 = checkClosed(items); - //$DELAY$ - if(!condition.run(recid, value, serializer)) - return recid; - - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - items2[position(recid)] = new HashItem(recid, value); - //$DELAY$ - }finally{ - lock.unlock(); - - } - //$DELAY$ - return recid; - } - - @Override - @SuppressWarnings("unchecked") - public A get(long recid, Serializer serializer) { - //$DELAY$ - final int pos = position(recid); - HashItem[] items2 = checkClosed(items); - HashItem item = items2[pos]; //TODO race condition? non volatile access - if(item!=null && recid == item.key) - return (A) item.val; - //$DELAY$ - Engine engine = getWrappedEngine(); - - - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - //not in cache, fetch and add - final A value = engine.get(recid, serializer); - if(value!=null && condition.run(recid, value, serializer)) - items2[pos] = new HashItem(recid, value); - //$DELAY$ - return value; - - }finally{ - lock.unlock(); - } - //$DELAY$ - } - - private int position(long recid) { - return DataIO.longHash(recid ^ hashSalt)&cacheMaxSizeMask; - } - - @Override - public void update(long recid, A value, Serializer serializer) { - if(!condition.run(recid, value, serializer)){ - super.update(recid,value,serializer); - return; - } - - //$DELAY$ - final int pos = position(recid); - HashItem[] items2 = checkClosed(items); - HashItem item = new HashItem(recid,value); - Engine engine = getWrappedEngine(); - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - items2[pos] = item; - engine.update(recid, value, serializer); - }finally { - lock.unlock(); - } - //$DELAY$ - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - if(!condition.run(recid, newValue, serializer)){ - return super.compareAndSwap(recid,expectedOldValue,newValue,serializer); - } - //$DELAY$ - - final int pos = position(recid); - HashItem[] items2 = checkClosed(items); - Engine engine = getWrappedEngine(); - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - HashItem item = items2[pos]; - if(item!=null && item.key == recid){ - //found in cache, so compare values - if(item.val == expectedOldValue || item.val.equals(expectedOldValue)){ - //$DELAY$ - //found matching entry in cache, so just update and return true - items2[pos] = new HashItem(recid, newValue); - engine.update(recid, newValue, serializer); - //$DELAY$ - return true; - }else{ - return false; - } - }else{ - boolean ret = engine.compareAndSwap(recid, expectedOldValue, newValue, serializer); - if(ret) items2[pos] = new HashItem(recid, newValue); - //$DELAY$ - return ret; - } - }finally { - lock.unlock(); - } - } - - @Override - public void delete(long recid, Serializer serializer){ - final int pos = position(recid); - HashItem[] items2 = checkClosed(items); - Engine engine = getWrappedEngine(); - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - engine.delete(recid,serializer); - HashItem item = items2[pos]; - //$DELAY$ - if(item!=null && recid == item.key) - items[pos] = null; - }finally { - lock.unlock(); - } - //$DELAY$ - } - - - @Override - public void close() { - super.close(); - //dereference to prevent memory leaks - items = null; - } - - @Override - public void rollback() { - //TODO lock all in caches on rollback/commit? - //$DELAY$ - for(int i = 0;iSoftReference or WeakReference - * Items can be removed from cache by Garbage Collector if - * - * @author Jan Kotek - */ - public static class WeakSoftRef extends EngineWrapper implements Engine { - - - protected final ReentrantLock[] locks; - protected final Fun.RecordCondition condition; - - protected final CountDownLatch cleanerFinished; - - protected interface CacheItem{ - long getRecid(); - Object get(); - void clear(); - } - - protected static final class CacheWeakItem extends WeakReference implements CacheItem { - - final long recid; - - public CacheWeakItem(A referent, ReferenceQueue q, long recid) { - super(referent, q); - this.recid = recid; - } - - @Override - public long getRecid() { - return recid; - } - } - - protected static final class CacheSoftItem extends SoftReference implements CacheItem { - - final long recid; - - public CacheSoftItem(A referent, ReferenceQueue q, long recid) { - super(referent, q); - this.recid = recid; - } - - @Override - public long getRecid() { - return recid; - } - } - - protected ReferenceQueue queue = new ReferenceQueue(); - - protected LongConcurrentHashMap items = new LongConcurrentHashMap(); - - - final protected boolean useWeakRef; - protected boolean shutdown = false; - - public WeakSoftRef(Engine engine, boolean useWeakRef, - Fun.RecordCondition condition, Fun.ThreadFactory threadFactory){ - super(engine); - locks = new ReentrantLock[CC.CONCURRENCY]; - for(int i=0;i queue = this.queue; - final LongConcurrentHashMap items = this.items; - if (queue == null || items==null) - return; - //$DELAY$ - while (!shutdown) { - CacheItem item = (CacheItem) queue.remove(200); - if(item==null) - continue; - //$DELAY$ - items.remove(item.getRecid(), item); - } - //$DELAY$ - items.clear(); - }catch(InterruptedException e){ - //this is expected, so just silently exit thread - }finally { - cleanerFinished.countDown(); - } - //$DELAY$ - } - - @Override - public long put(A value, Serializer serializer) { - long recid = getWrappedEngine().put(value, serializer); - //$DELAY$ - if(!condition.run(recid, value, serializer)) - return recid; - //$DELAY$ - ReferenceQueue q = (ReferenceQueue) checkClosed(queue); - LongConcurrentHashMap items2 = checkClosed(items); - CacheItem item = useWeakRef? - new CacheWeakItem(value, q, recid) : - new CacheSoftItem(value, q, recid); - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - CacheItem old = items2.put(recid,item); - if(old!=null) - old.clear(); - //$DELAY$ - }finally{ - lock.unlock(); - } - //$DELAY$ - return recid; - } - - @SuppressWarnings("unchecked") - @Override - public A get(long recid, Serializer serializer) { - //$DELAY$ - LongConcurrentHashMap items2 = checkClosed(items); - CacheItem item = items2.get(recid); - //$DELAY$ - if(item!=null){ - Object o = item.get(); - //$DELAY$ - if(o == null) - items2.remove(recid); - else{ - return (A) o; - } - } - - Engine engine = getWrappedEngine(); - - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - Object value = engine.get(recid, serializer); - if(value!=null && condition.run(recid, value, serializer)){ - ReferenceQueue q = (ReferenceQueue) checkClosed(queue); - //$DELAY$ - item = useWeakRef? - new CacheWeakItem(value, q, recid) : - new CacheSoftItem(value, q, recid); - CacheItem old = items2.put(recid,item); - //$DELAY$ - if(old!=null) - old.clear(); - } - //$DELAY$ - return (A) value; - }finally{ - lock.unlock(); - } - //$DELAY$ - - } - - @Override - public void update(long recid, A value, Serializer serializer) { - //$DELAY$ - if(!condition.run(recid, value, serializer)){ - //$DELAY$ - super.update(recid,value,serializer); - return; - } - //$DELAY$ - - Engine engine = getWrappedEngine(); - ReferenceQueue q = (ReferenceQueue) checkClosed(queue); - LongConcurrentHashMap items2 = checkClosed(items); - //$DELAY$ - CacheItem item = useWeakRef? - new CacheWeakItem(value, q, recid) : - new CacheSoftItem(value, q, recid); - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - CacheItem old = items2.put(recid,item); - if(old!=null) - old.clear(); - //$DELAY$ - engine.update(recid, value, serializer); - }finally { - lock.unlock(); - } - //$DELAY$ - } - - - @Override - public void delete(long recid, Serializer serializer){ - Engine engine = getWrappedEngine(); - LongMap items2 = checkClosed(items); - //$DELAY$ - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - CacheItem old = items2.remove(recid); - if(old!=null) - old.clear(); - //$DELAY$ - engine.delete(recid,serializer); - }finally { - lock.unlock(); - } - //$DELAY$ - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - //$DELAY$ - if(!condition.run(recid, newValue, serializer)){ - //$DELAY$ - return super.compareAndSwap(recid,expectedOldValue,newValue,serializer); - } - //$DELAY$ - Engine engine = getWrappedEngine(); - LongMap items2 = checkClosed(items); - ReferenceQueue q = (ReferenceQueue) checkClosed(queue); - - - final Lock lock = locks[Store.lockPos(recid)]; - lock.lock(); - //$DELAY$ - try{ - CacheItem item = items2.get(recid); - Object oldValue = item==null? null: item.get() ; - //$DELAY$ - if(item!=null && item.getRecid() == recid && - (oldValue == expectedOldValue || (oldValue!=null && oldValue.equals(expectedOldValue)))){ - //found matching entry in cache, so just update and return true - //$DELAY$ - CacheItem old = items2.put(recid,useWeakRef? - new CacheWeakItem(newValue, q, recid) : - new CacheSoftItem(newValue, q, recid)); - //$DELAY$ - if(old!=null) - old.clear(); - engine.update(recid, newValue, serializer); - //$DELAY$ - return true; - }else{ - boolean ret = engine.compareAndSwap(recid, expectedOldValue, newValue, serializer); - if(ret){ - //$DELAY$ - CacheItem old = items2.put(recid,useWeakRef? - new CacheWeakItem(newValue, q, recid) : - new CacheSoftItem(newValue, q, recid)); - if(old!=null) - old.clear(); - } - return ret; - } - }finally { - lock.unlock(); - } - //$DELAY$ - } - - - @Override - public void close() { - shutdown = true; - super.close(); - items = null; - queue = null; - try { - cleanerFinished.await(); - //TODO should we wait for cleaner threads to shutdown? I guess it prevents memory leaks - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - - @Override - public void rollback() { - items.clear(); - super.rollback(); - } - - @Override - public void clearCache() { - // release all items so those are not passed to Queue - LongMap.LongMapIterator iter = items.longMapIterator(); - //$DELAY$ - while(iter.moveToNext()){ - //$DELAY$ - CacheItem i = iter.value(); - if(i!=null) - i.clear(); - } - - items.clear(); - super.clearCache(); - } - - } - - /** - * Cache created objects using hard reference. - * It checks free memory every N operations (1024*10). If free memory is bellow 75% it clears the cache - * - * @author Jan Kotek - */ - public static class HardRef extends LRU { - - final static int CHECK_EVERY_N = 0xFFFF; - - int counter = 0; - - public HardRef(Engine engine, int initialCapacity, Fun.RecordCondition condition) { - super(engine, new LongConcurrentHashMap(initialCapacity), condition); - } - - - @Override - public A get(long recid, Serializer serializer) { - //$DELAY$ - if(((counter++)& CHECK_EVERY_N)==0 ) { - checkFreeMem(); - } - return super.get(recid, serializer); - } - - private void checkFreeMem() { - Runtime r = Runtime.getRuntime(); - long max = r.maxMemory(); - if(max == Long.MAX_VALUE) - return; - - double free = r.freeMemory(); - double total = r.totalMemory(); - //We believe that free refers to total not max. - //Increasing heap size to max would increase to max - free = free + (max-total); - - if(CC.LOG_EWRAP && LOG.isLoggable(Level.FINE)) - LOG.fine("HardRefCache: freemem = " +free + " = "+(free/max)+"%"); - //$DELAY$ - if(free<1e7 || free*4 void update(long recid, A value, Serializer serializer) { - if(((counter++)& CHECK_EVERY_N)==0 ) { - checkFreeMem(); - } - //$DELAY$ - super.update(recid, value, serializer); - } - - @Override - public void delete(long recid, Serializer serializer){ - if(((counter++)& CHECK_EVERY_N)==0 ) { - checkFreeMem(); - } - - super.delete(recid,serializer); - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - if(((counter++)& CHECK_EVERY_N)==0 ) { - checkFreeMem(); - } - return super.compareAndSwap(recid, expectedOldValue, newValue, serializer); - } - } -} diff --git a/src/main/java/org/mapdb/CompressLZF.java b/src/main/java/org/mapdb/CompressLZF.java deleted file mode 100644 index 0704cea8b..000000000 --- a/src/main/java/org/mapdb/CompressLZF.java +++ /dev/null @@ -1,404 +0,0 @@ -/* - * This code comes from H2 database project and was modified for MapDB a bit. - * Re-licensed under Apache 2 license with Thomas Mueller permission - * - * Copyright (c) 2004-2011 H2 Group - * - * 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 - * - * http://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. - */ - - -/* - * Original H2 license - * - * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * - * This code is based on the LZF algorithm from Marc Lehmann. It is a - * re-implementation of the C code: - * http://cvs.schmorp.de/liblzf/lzf_c.c?view=markup - * http://cvs.schmorp.de/liblzf/lzf_d.c?view=markup - * - * According to a mail from Marc Lehmann, it's OK to use his algorithm: - * Date: 2010-07-15 15:57 - * Subject: Re: Question about LZF licensing - * ... - * The algorithm is not copyrighted (and cannot be copyrighted afaik) - as long - * as you wrote everything yourself, without copying my code, that's just fine - * (looking is of course fine too). - * ... - * - * Still I would like to keep his copyright info: - * - * Copyright (c) 2000-2005 Marc Alexander Lehmann - * Copyright (c) 2005 Oren J. Maurice - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.mapdb; - -import java.io.DataInput; -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - *

- * This class implements the LZF lossless data compression algorithm. LZF is a - * Lempel-Ziv variant with byte-aligned output, and optimized for speed. - *

- *

- * Safety/Use Notes: - *

- *
    - *
  • Each instance should be used by a single thread only.
  • - *
  • The data buffers should be smaller than 1 GB.
  • - *
  • For performance reasons, safety checks on expansion are omitted.
  • - *
  • Invalid compressed data can cause an ArrayIndexOutOfBoundsException.
  • - *
- *

- * The LZF compressed format knows literal runs and back-references: - *

- *
    - *
  • Literal run: directly copy bytes from input to output.
  • - *
  • Back-reference: copy previous data to output stream, with specified - * offset from location and length. The length is at least 3 bytes.
  • - *
- *

- * The first byte of the compressed stream is the control byte. For literal - * runs, the highest three bits of the control byte are not set, the the lower - * bits are the literal run length, and the next bytes are data to copy directly - * into the output. For back-references, the highest three bits of the control - * byte are the back-reference length. If all three bits are set, then the - * back-reference length is stored in the next byte. The lower bits of the - * control byte combined with the next byte form the offset for the - * back-reference. - *

- */ -public final class CompressLZF{ - - /** - * The number of entries in the hash table. The size is a trade-off between - * hash collisions (reduced compression) and speed (amount that fits in CPU - * cache). - */ - private static final int HASH_SIZE = 1 << 14; - - /** - * The maximum number of literals in a chunk (32). - */ - private static final int MAX_LITERAL = 1 << 5; - - /** - * The maximum offset allowed for a back-reference (8192). - */ - private static final int MAX_OFF = 1 << 13; - - /** - * The maximum back-reference length (264). - */ - private static final int MAX_REF = (1 << 8) + (1 << 3); - - /** - * Hash table for matching byte sequences (reused for performance). - */ - private int[] cachedHashTable; - - /** - * Return byte with lower 2 bytes being byte at index, then index+1. - */ - private static int first(byte[] in, int inPos) { - return (in[inPos] << 8) | (in[inPos + 1] & 255); - } - - /** - * Shift v 1 byte left, add value at index inPos+2. - */ - private static int next(int v, byte[] in, int inPos) { - return (v << 8) | (in[inPos + 2] & 255); - } - - /** - * Compute the address in the hash table. - */ - private static int hash(int h) { - return ((h * 2777) >> 9) & (HASH_SIZE - 1); - } - - public int compress(byte[] in, int inLen, byte[] out, int outPos) { - int inPos = 0; - if (cachedHashTable == null) { - cachedHashTable = new int[HASH_SIZE]; - } - int[] hashTab = cachedHashTable; - int literals = 0; - outPos++; - int future = first(in, 0); - while (inPos < inLen - 4) { - byte p2 = in[inPos + 2]; - // next - future = (future << 8) + (p2 & 255); - int off = hash(future); - int ref = hashTab[off]; - hashTab[off] = inPos; - // if (ref < inPos - // && ref > 0 - // && (off = inPos - ref - 1) < MAX_OFF - // && in[ref + 2] == p2 - // && (((in[ref] & 255) << 8) | (in[ref + 1] & 255)) == - // ((future >> 8) & 0xffff)) { - if (ref < inPos - && ref > 0 - && (off = inPos - ref - 1) < MAX_OFF - && in[ref + 2] == p2 - && in[ref + 1] == (byte) (future >> 8) - && in[ref] == (byte) (future >> 16)) { - // match - int maxLen = inLen - inPos - 2; - if (maxLen > MAX_REF) { - maxLen = MAX_REF; - } - if (literals == 0) { - // multiple back-references, - // so there is no literal run control byte - outPos--; - } else { - // set the control byte at the start of the literal run - // to store the number of literals - out[outPos - literals - 1] = (byte) (literals - 1); - literals = 0; - } - int len = 3; - while (len < maxLen && in[ref + len] == in[inPos + len]) { - len++; - } - len -= 2; - if (len < 7) { - out[outPos++] = (byte) ((off >> 8) + (len << 5)); - } else { - out[outPos++] = (byte) ((off >> 8) + (7 << 5)); - out[outPos++] = (byte) (len - 7); - } - out[outPos++] = (byte) off; - // move one byte forward to allow for a literal run control byte - outPos++; - inPos += len; - // rebuild the future, and store the last bytes to the hashtable. - // Storing hashes of the last bytes in back-reference improves - // the compression ratio and only reduces speed slightly. - future = first(in, inPos); - future = next(future, in, inPos); - hashTab[hash(future)] = inPos++; - future = next(future, in, inPos); - hashTab[hash(future)] = inPos++; - } else { - // copy one byte from input to output as part of literal - out[outPos++] = in[inPos++]; - literals++; - // at the end of this literal chunk, write the length - // to the control byte and start a new chunk - if (literals == MAX_LITERAL) { - out[outPos - literals - 1] = (byte) (literals - 1); - literals = 0; - // move ahead one byte to allow for the - // literal run control byte - outPos++; - } - } - } - // write the remaining few bytes as literals - while (inPos < inLen) { - out[outPos++] = in[inPos++]; - literals++; - if (literals == MAX_LITERAL) { - out[outPos - literals - 1] = (byte) (literals - 1); - literals = 0; - outPos++; - } - } - // writes the final literal run length to the control byte - out[outPos - literals - 1] = (byte) (literals - 1); - if (literals == 0) { - outPos--; - } - return outPos; - } - - public void expand(DataInput in, byte[] out, int outPos, int outLen) throws IOException { - // if ((inPos | outPos | outLen) < 0) { - if(CC.PARANOID && ! (outLen>=0)) - throw new AssertionError(); - do { - int ctrl = in.readByte() & 255; - if (ctrl < MAX_LITERAL) { - // literal run of length = ctrl + 1, - ctrl++; - // copy to output and move forward this many bytes - in.readFully(out,outPos,ctrl); - outPos += ctrl; - } else { - // back reference - // the highest 3 bits are the match length - int len = ctrl >> 5; - // if the length is maxed, add the next byte to the length - if (len == 7) { - len += in.readByte() & 255; - } - // minimum back-reference is 3 bytes, - // so 2 was subtracted before storing size - len += 2; - - // ctrl is now the offset for a back-reference... - // the logical AND operation removes the length bits - ctrl = -((ctrl & 0x1f) << 8) - 1; - - // the next byte augments/increases the offset - ctrl -= in.readByte() & 255; - - // copy the back-reference bytes from the given - // location in output to current position - ctrl += outPos; - if (outPos + len >= out.length) { - // reduce array bounds checking - throw new ArrayIndexOutOfBoundsException(); - } - for (int i = 0; i < len; i++) { - out[outPos++] = out[ctrl++]; - } - } - } while (outPos < outLen); - } - - - public void expand(ByteBuffer in, int inPos, byte[] out, int outPos, int outLen) { - ByteBuffer in2=null; - if(CC.PARANOID && ! (outLen>=0)) - throw new AssertionError(); - do { - int ctrl = in.get(inPos++) & 255; - if (ctrl < MAX_LITERAL) { - // literal run of length = ctrl + 1, - ctrl++; - // copy to output and move forward this many bytes - //System.arraycopy(in, inPos, out, outPos, ctrl); - if(in2==null) in2 = in.duplicate(); - in2.position(inPos); - in2.get(out,outPos,ctrl); - outPos += ctrl; - inPos += ctrl; - } else { - // back reference - // the highest 3 bits are the match length - int len = ctrl >> 5; - // if the length is maxed, add the next byte to the length - if (len == 7) { - len += in.get(inPos++) & 255; - } - // minimum back-reference is 3 bytes, - // so 2 was subtracted before storing size - len += 2; - - // ctrl is now the offset for a back-reference... - // the logical AND operation removes the length bits - ctrl = -((ctrl & 0x1f) << 8) - 1; - - // the next byte augments/increases the offset - ctrl -= in.get(inPos++) & 255; - - // copy the back-reference bytes from the given - // location in output to current position - ctrl += outPos; - if (outPos + len >= out.length) { - // reduce array bounds checking - throw new ArrayIndexOutOfBoundsException(); - } - for (int i = 0; i < len; i++) { - out[outPos++] = out[ctrl++]; - } - } - } while (outPos < outLen); - } - - public void expand(byte[] in, int inPos, byte[] out, int outPos, int outLen) { - // if ((inPos | outPos | outLen) < 0) { - if (inPos < 0 || outPos < 0 || outLen < 0) { - throw new IllegalArgumentException(); - } - do { - int ctrl = in[inPos++] & 255; - if (ctrl < MAX_LITERAL) { - // literal run of length = ctrl + 1, - ctrl++; - // copy to output and move forward this many bytes - System.arraycopy(in, inPos, out, outPos, ctrl); - outPos += ctrl; - inPos += ctrl; - } else { - // back reference - // the highest 3 bits are the match length - int len = ctrl >> 5; - // if the length is maxed, add the next byte to the length - if (len == 7) { - len += in[inPos++] & 255; - } - // minimum back-reference is 3 bytes, - // so 2 was subtracted before storing size - len += 2; - - // ctrl is now the offset for a back-reference... - // the logical AND operation removes the length bits - ctrl = -((ctrl & 0x1f) << 8) - 1; - - // the next byte augments/increases the offset - ctrl -= in[inPos++] & 255; - - // copy the back-reference bytes from the given - // location in output to current position - ctrl += outPos; - if (outPos + len >= out.length) { - // reduce array bounds checking - throw new ArrayIndexOutOfBoundsException(); - } - for (int i = 0; i < len; i++) { - out[outPos++] = out[ctrl++]; - } - } - } while (outPos < outLen); - } - - - -} \ No newline at end of file diff --git a/src/main/java/org/mapdb/DB.java b/src/main/java/org/mapdb/DB.java deleted file mode 100644 index 171a96de2..000000000 --- a/src/main/java/org/mapdb/DB.java +++ /dev/null @@ -1,1679 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.io.Closeable; -import java.io.IOError; -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.*; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; - -/** - * A database with easy access to named maps and other collections. - * - * @author Jan Kotek - */ -//TODO DB uses global lock, replace it with ReadWrite lock or fine grained locking. -@SuppressWarnings("unchecked") -public class DB implements Closeable { - - protected final boolean strictDBGet; - - /** Engine which provides persistence for this DB*/ - protected Engine engine; - /** already loaded named collections. It is important to keep collections as singletons, because of 'in-memory' locking*/ - protected Map> namesInstanciated = new HashMap>(); - - protected Map namesLookup = - Collections.synchronizedMap( //TODO remove synchronized map, after DB locking is resolved - new HashMap()); - - /** view over named records */ - protected SortedMap catalog; - - protected final Fun.ThreadFactory threadFactory = Fun.ThreadFactory.BASIC; - - protected static class IdentityWrapper{ - - final Object o; - - public IdentityWrapper(Object o) { - this.o = o; - } - - @Override - public int hashCode() { - return System.identityHashCode(o); - } - - @Override - public boolean equals(Object v) { - return ((IdentityWrapper)v).o==o; - } - } - - /** - * Construct new DB. It is just thin layer over {@link Engine} which does the real work. - * @param engine - */ - public DB(final Engine engine){ - this(engine,false,false); - } - - public DB(Engine engine, boolean strictDBGet, boolean disableLocks) { - if(!(engine instanceof EngineWrapper)){ - //access to Store should be prevented after `close()` was called. - //So for this we have to wrap raw Store into EngineWrapper - engine = new EngineWrapper(engine); - } - this.engine = engine; - this.strictDBGet = strictDBGet; - engine.getSerializerPojo().setDb(this); - //$DELAY$ - reinit(); - //$DELAY$ - } - - protected void reinit() { - //open name dir - //$DELAY$ - catalog = BTreeMap.preinitCatalog(this); - } - - public
A catGet(String name, A init){ - if(CC.PARANOID && ! (Thread.holdsLock(DB.this))) - throw new AssertionError(); - A ret = (A) catalog.get(name); - return ret!=null? ret : init; - } - - - public A catGet(String name){ - if(CC.PARANOID && ! (Thread.holdsLock(DB.this))) - throw new AssertionError(); - //$DELAY$ - return (A) catalog.get(name); - } - - public A catPut(String name, A value){ - if(CC.PARANOID && ! (Thread.holdsLock(DB.this))) - throw new AssertionError(); - //$DELAY$ - catalog.put(name, value); - return value; - } - - public A catPut(String name, A value, A retValueIfNull){ - if(CC.PARANOID && ! (Thread.holdsLock(DB.this))) - throw new AssertionError(); - if(value==null) return retValueIfNull; - //$DELAY$ - catalog.put(name, value); - return value; - } - - /** returns name for this object, if it has name and was instanciated by this DB*/ - public String getNameForObject(Object obj) { - //TODO this method should be synchronized, but it causes deadlock. - return namesLookup.get(new IdentityWrapper(obj)); - } - - - public class HTreeMapMaker{ - protected final String name; - - public HTreeMapMaker(String name) { - this.name = name; - } - - - protected boolean counter = false; - protected Serializer keySerializer = null; - protected Serializer valueSerializer = null; - protected long expireMaxSize = 0L; - protected long expire = 0L; - protected long expireAccess = 0L; - protected long expireStoreSize; - protected Hasher hasher = null; - - protected Fun.Function1 valueCreator = null; - - - - - /** by default collection does not have counter, without counter updates are faster, but entire collection needs to be traversed to count items.*/ - public HTreeMapMaker counterEnable(){ - this.counter = true; - return this; - } - - - - /** keySerializer used to convert keys into/from binary form. */ - public HTreeMapMaker keySerializer(Serializer keySerializer){ - this.keySerializer = keySerializer; - return this; - } - - /** valueSerializer used to convert values into/from binary form. */ - public HTreeMapMaker valueSerializer(Serializer valueSerializer){ - this.valueSerializer = valueSerializer; - return this; - } - - /** maximal number of entries in this map. Less used entries will be expired and removed to make collection smaller */ - public HTreeMapMaker expireMaxSize(long maxSize){ - this.expireMaxSize = maxSize; - this.counter = true; - return this; - } - - /** Specifies that each entry should be automatically removed from the map once a fixed duration has elapsed after the entry's creation, or the most recent replacement of its value. */ - public HTreeMapMaker expireAfterWrite(long interval, TimeUnit timeUnit){ - this.expire = timeUnit.toMillis(interval); - return this; - } - - /** Specifies that each entry should be automatically removed from the map once a fixed duration has elapsed after the entry's creation, or the most recent replacement of its value. */ - public HTreeMapMaker expireAfterWrite(long interval){ - this.expire = interval; - return this; - } - - /** Specifies that each entry should be automatically removed from the map once a fixed duration has elapsed after the entry's creation, the most recent replacement of its value, or its last access. Access time is reset by all map read and write operations */ - public HTreeMapMaker expireAfterAccess(long interval, TimeUnit timeUnit){ - this.expireAccess = timeUnit.toMillis(interval); - return this; - } - - /** Specifies that each entry should be automatically removed from the map once a fixed duration has elapsed after the entry's creation, the most recent replacement of its value, or its last access. Access time is reset by all map read and write operations */ - public HTreeMapMaker expireAfterAccess(long interval){ - this.expireAccess = interval; - return this; - } - - public HTreeMapMaker expireStoreSize(double maxStoreSize) { - this.expireStoreSize = (long) (maxStoreSize*1024L*1024L*1024L); - return this; - } - - /** If value is not found, HTreeMap can fetch and insert default value. `valueCreator` is used to return new value. - * This way `HTreeMap.get()` never returns null */ - public HTreeMapMaker valueCreator(Fun.Function1 valueCreator){ - this.valueCreator = valueCreator; - return this; - } - - public HTreeMapMaker hasher(Hasher hasher){ - this.hasher = hasher; - return this; - } - - - public HTreeMap make(){ - if(expireMaxSize!=0) counter =true; - return DB.this.createHashMap(HTreeMapMaker.this); - } - - public HTreeMap makeOrGet(){ - //$DELAY$ - synchronized (DB.this){ - //TODO add parameter check - //$DELAY$ - return (HTreeMap) (catGet(name+".type")==null? - make():getHashMap(name)); - } - } - - - } - - public class HTreeSetMaker{ - protected final String name; - - public HTreeSetMaker(String name) { - this.name = name; - } - - protected boolean counter = false; - protected Serializer serializer = null; - protected long expireMaxSize = 0L; - protected long expireStoreSize = 0L; - protected long expire = 0L; - protected long expireAccess = 0L; - protected Hasher hasher = null; - - /** by default collection does not have counter, without counter updates are faster, but entire collection needs to be traversed to count items.*/ - public HTreeSetMaker counterEnable(){ - this.counter = true; - return this; - } - - - /** keySerializer used to convert keys into/from binary form. */ - public HTreeSetMaker serializer(Serializer serializer){ - this.serializer = serializer; - return this; - } - - - /** maximal number of entries in this map. Less used entries will be expired and removed to make collection smaller */ - public HTreeSetMaker expireMaxSize(long maxSize){ - this.expireMaxSize = maxSize; - this.counter = true; - return this; - } - - /** maximal size of store in GB, if store is larger entries will start expiring */ - public HTreeSetMaker expireStoreSize(double maxStoreSize){ - this.expireStoreSize = (long) (maxStoreSize * 1024L * 1024L * 1024L); - return this; - } - - /** Specifies that each entry should be automatically removed from the map once a fixed duration has elapsed after the entry's creation, or the most recent replacement of its value. */ - public HTreeSetMaker expireAfterWrite(long interval, TimeUnit timeUnit){ - this.expire = timeUnit.toMillis(interval); - return this; - } - - /** Specifies that each entry should be automatically removed from the map once a fixed duration has elapsed after the entry's creation, or the most recent replacement of its value. */ - public HTreeSetMaker expireAfterWrite(long interval){ - this.expire = interval; - return this; - } - - /** Specifies that each entry should be automatically removed from the map once a fixed duration has elapsed after the entry's creation, the most recent replacement of its value, or its last access. Access time is reset by all map read and write operations */ - public HTreeSetMaker expireAfterAccess(long interval, TimeUnit timeUnit){ - this.expireAccess = timeUnit.toMillis(interval); - return this; - } - - /** Specifies that each entry should be automatically removed from the map once a fixed duration has elapsed after the entry's creation, the most recent replacement of its value, or its last access. Access time is reset by all map read and write operations */ - public HTreeSetMaker expireAfterAccess(long interval){ - this.expireAccess = interval; - return this; - } - - - public HTreeSetMaker hasher(Hasher hasher){ - this.hasher = hasher; - return this; - } - - - public Set make(){ - if(expireMaxSize!=0) counter =true; - return DB.this.createHashSet(HTreeSetMaker.this); - } - - public Set makeOrGet(){ - synchronized (DB.this){ - //$DELAY$ - //TODO add parameter check - return (Set) (catGet(name+".type")==null? - make():getHashSet(name)); - } - } - - } - - - - /** - * Opens existing or creates new Hash Tree Map. - * This collection perform well under concurrent access. - * Is best for large keys and large values. - * - * @param name of the map - * @return map - */ - synchronized public HTreeMap getHashMap(String name){ - return getHashMap(name, null); - } - - /** - * Opens existing or creates new Hash Tree Map. - * This collection perform well under concurrent access. - * Is best for large keys and large values. - * - * @param name of map - * @param valueCreator if value is not found, new is created and placed into map. - * @return map - */ - synchronized public HTreeMap getHashMap(String name, Fun.Function1 valueCreator){ - checkNotClosed(); - HTreeMap ret = (HTreeMap) getFromWeakCollection(name); - if(ret!=null) return ret; - String type = catGet(name + ".type", null); - //$DELAY$ - if(type==null){ - //$DELAY$ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - //$DELAY$ - new DB(e).getHashMap("a"); - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getHashMap("a")); - } - if(valueCreator!=null) - return createHashMap(name).valueCreator(valueCreator).make(); - return createHashMap(name).make(); - } - - - //check type - checkType(type, "HashMap"); - //open existing map - //$DELAY$ - ret = new HTreeMap(engine, - (Long)catGet(name+".counterRecid"), - (Integer)catGet(name+".hashSalt"), - (long[])catGet(name+".segmentRecids"), - catGet(name+".keySerializer",getDefaultSerializer()), - catGet(name+".valueSerializer",getDefaultSerializer()), - catGet(name+".expireTimeStart",0L), - catGet(name+".expire",0L), - catGet(name+".expireAccess",0L), - catGet(name+".expireMaxSize",0L), - catGet(name+".expireStoreSize",0L), - (long[])catGet(name+".expireHeads",null), - (long[])catGet(name+".expireTails",null), - valueCreator, - catGet(name+".hasher", Hasher.BASIC), - false, - threadFactory); - - //$DELAY$ - namedPut(name, ret); - //$DELAY$ - return ret; - } - - public V namedPut(String name, Object ret) { - //$DELAY$ - namesInstanciated.put(name, new WeakReference(ret)); - //$DELAY$ - namesLookup.put(new IdentityWrapper(ret), name); - return (V) ret; - } - - - /** - * Returns new builder for HashMap with given name - * - * @param name of map to create - * @throws IllegalArgumentException if name is already used - * @return maker, call `.make()` to create map - */ - public HTreeMapMaker createHashMap(String name){ - return new HTreeMapMaker(name); - } - - - - /** - * Creates new HashMap with more specific arguments - * - * @throws IllegalArgumentException if name is already used - * @return newly created map - */ - synchronized protected HTreeMap createHashMap(HTreeMapMaker m){ - String name = m.name; - checkNameNotExists(name); - //$DELAY$ - long expireTimeStart=0, expire=0, expireAccess=0, expireMaxSize = 0, expireStoreSize=0; - long[] expireHeads=null, expireTails=null; - - if(m.expire!=0 || m.expireAccess!=0 || m.expireMaxSize !=0 || m.expireStoreSize!=0){ - expireTimeStart = catPut(name+".expireTimeStart",System.currentTimeMillis()); - expire = catPut(name+".expire",m.expire); - expireAccess = catPut(name+".expireAccess",m.expireAccess); - expireMaxSize = catPut(name+".expireMaxSize",m.expireMaxSize); - expireStoreSize = catPut(name+".expireStoreSize",m.expireStoreSize); - //$DELAY$ - expireHeads = new long[16]; - expireTails = new long[16]; - for(int i=0;i<16;i++){ - expireHeads[i] = engine.put(0L,Serializer.LONG); - expireTails[i] = engine.put(0L,Serializer.LONG); - } - catPut(name+".expireHeads",expireHeads); - catPut(name+".expireTails",expireHeads); - } - //$DELAY$ - if(m.hasher!=null){ - catPut(name+".hasher",m.hasher); - } - - - HTreeMap ret = new HTreeMap(engine, - catPut(name+".counterRecid",!m.counter ?0L:engine.put(0L, Serializer.LONG)), - catPut(name+".hashSalt",new Random().nextInt()), - catPut(name+".segmentRecids",HTreeMap.preallocateSegments(engine)), - catPut(name+".keySerializer",m.keySerializer,getDefaultSerializer()), - catPut(name+".valueSerializer",m.valueSerializer,getDefaultSerializer()), - expireTimeStart,expire,expireAccess,expireMaxSize, expireStoreSize, expireHeads ,expireTails, - (Fun.Function1) m.valueCreator, m.hasher,false, - threadFactory - - ); - //$DELAY$ - catalog.put(name + ".type", "HashMap"); - namedPut(name, ret); - return ret; - } - - /** - * Opens existing or creates new Hash Tree Set. - * - * @param name of the Set - * @return set - */ - synchronized public Set getHashSet(String name){ - checkNotClosed(); - Set ret = (Set) getFromWeakCollection(name); - if(ret!=null) return ret; - String type = catGet(name + ".type", null); - //$DELAY$ - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - //$DELAY$ - new DB(e).getHashSet("a"); - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getHashSet("a")); - } - return createHashSet(name).makeOrGet(); - //$DELAY$ - } - - - //check type - checkType(type, "HashSet"); - //open existing map - ret = new HTreeMap(engine, - (Long)catGet(name+".counterRecid"), - (Integer)catGet(name+".hashSalt"), - (long[])catGet(name+".segmentRecids"), - catGet(name+".serializer",getDefaultSerializer()), - null, 0L,0L,0L,0L,0L,null,null,null, - catGet(name+".hasher",Hasher.BASIC), - false, - threadFactory - ).keySet(); - - //$DELAY$ - namedPut(name, ret); - //$DELAY$ - return ret; - } - - /** - * Creates new HashSet - * - * @param name of set to create - */ - synchronized public HTreeSetMaker createHashSet(String name){ - return new HTreeSetMaker(name); - } - - - synchronized protected Set createHashSet(HTreeSetMaker m){ - String name = m.name; - checkNameNotExists(name); - - long expireTimeStart=0, expire=0, expireAccess=0, expireMaxSize = 0, expireStoreSize = 0; - long[] expireHeads=null, expireTails=null; - - if(m.expire!=0 || m.expireAccess!=0 || m.expireMaxSize !=0){ - expireTimeStart = catPut(name+".expireTimeStart",System.currentTimeMillis()); - expire = catPut(name+".expire",m.expire); - expireAccess = catPut(name+".expireAccess",m.expireAccess); - expireMaxSize = catPut(name+".expireMaxSize",m.expireMaxSize); - expireStoreSize = catPut(name+".expireStoreSize",m.expireStoreSize); - expireHeads = new long[16]; - //$DELAY$ - expireTails = new long[16]; - for(int i=0;i<16;i++){ - expireHeads[i] = engine.put(0L,Serializer.LONG); - expireTails[i] = engine.put(0L,Serializer.LONG); - } - catPut(name+".expireHeads",expireHeads); - catPut(name+".expireTails",expireHeads); - } - //$DELAY$ - if(m.hasher!=null){ - catPut(name+".hasher",m.hasher); - } - - //$DELAY$ - HTreeMap ret = new HTreeMap(engine, - catPut(name+".counterRecid",!m.counter ?0L:engine.put(0L, Serializer.LONG)), - catPut(name+".hashSalt",new Random().nextInt()), - catPut(name+".segmentRecids",HTreeMap.preallocateSegments(engine)), - catPut(name+".serializer",m.serializer,getDefaultSerializer()), - null, - expireTimeStart,expire,expireAccess,expireMaxSize, expireStoreSize, expireHeads ,expireTails, - null, m.hasher, false, - threadFactory - ); - Set ret2 = ret.keySet(); - //$DELAY$ - catalog.put(name + ".type", "HashSet"); - namedPut(name, ret2); - //$DELAY$ - return ret2; - } - - - - public class BTreeMapMaker{ - protected final String name; - - public BTreeMapMaker(String name) { - this.name = name; - } - - protected int nodeSize = 32; - protected boolean valuesOutsideNodes = false; - protected boolean counter = false; - protected BTreeKeySerializer keySerializer; - protected Serializer valueSerializer; - protected Comparator comparator; - - protected Iterator pumpSource; - protected Fun.Function1 pumpKeyExtractor; - protected Fun.Function1 pumpValueExtractor; - protected int pumpPresortBatchSize = -1; - protected boolean pumpIgnoreDuplicates = false; - - - /** nodeSize maximal size of node, larger node causes overflow and creation of new BTree node. Use large number for small keys, use small number for large keys.*/ - public BTreeMapMaker nodeSize(int nodeSize){ - if(nodeSize>=BTreeMap.NodeSerializer.SIZE_MASK) - throw new IllegalArgumentException("Too large max node size"); - this.nodeSize = nodeSize; - return this; - } - - /** by default values are stored inside BTree Nodes. Large values should be stored outside of BTreeNodes*/ - public BTreeMapMaker valuesOutsideNodesEnable(){ - this.valuesOutsideNodes = true; - return this; - } - - /** by default collection does not have counter, without counter updates are faster, but entire collection needs to be traversed to count items.*/ - public BTreeMapMaker counterEnable(){ - this.counter = true; - return this; - } - - /** keySerializer used to convert keys into/from binary form. */ - public BTreeMapMaker keySerializer(BTreeKeySerializer keySerializer){ - this.keySerializer = keySerializer; - return this; - } - /** keySerializer used to convert keys into/from binary form. - * This wraps ordinary serializer, with no delta packing used*/ - public BTreeMapMaker keySerializer(Serializer serializer){ - this.keySerializer = new BTreeKeySerializer.BasicKeySerializer(serializer, comparator); - return this; - } - - /** valueSerializer used to convert values into/from binary form. */ - public BTreeMapMaker valueSerializer(Serializer valueSerializer){ - this.valueSerializer = valueSerializer; - return this; - } - - /** comparator used to sort keys. */ - public BTreeMapMaker comparator(Comparator comparator){ - this.comparator = comparator; - return this; - } - - public BTreeMapMaker pumpSource(Iterator keysSource, Fun.Function1 valueExtractor){ - this.pumpSource = keysSource; - this.pumpKeyExtractor = Fun.extractNoTransform(); - this.pumpValueExtractor = valueExtractor; - return this; - } - - - public BTreeMapMaker pumpSource(Iterator> entriesSource){ - this.pumpSource = entriesSource; - this.pumpKeyExtractor = Fun.extractKey(); - this.pumpValueExtractor = Fun.extractValue(); - return this; - } - - public BTreeMapMaker pumpPresort(int batchSize){ - this.pumpPresortBatchSize = batchSize; - return this; - } - - - /** - * If source iteretor contains an duplicate key, exception is thrown. - * This options will only use firts key and ignore any consequentive duplicates. - */ - public BTreeMapMaker pumpIgnoreDuplicates(){ - this.pumpIgnoreDuplicates = true; - return this; - } - - public BTreeMap make(){ - return DB.this.createTreeMap(BTreeMapMaker.this); - } - - public BTreeMap makeOrGet(){ - synchronized(DB.this){ - //TODO add parameter check - return (BTreeMap) (catGet(name+".type")==null? - make():getTreeMap(name)); - } - } - - - /** creates map optimized for using `String` keys */ - public BTreeMap makeStringMap() { - keySerializer = BTreeKeySerializer.STRING; - return make(); - } - - /** creates map optimized for using zero or positive `Long` keys */ - public BTreeMap makeLongMap() { - keySerializer = BTreeKeySerializer.ZERO_OR_POSITIVE_LONG; - return make(); - } - - } - - public class BTreeSetMaker{ - protected final String name; - - public BTreeSetMaker(String name) { - this.name = name; - } - - protected int nodeSize = 32; - protected boolean counter = false; - protected BTreeKeySerializer serializer; - protected Comparator comparator; - - protected Iterator pumpSource; - protected int pumpPresortBatchSize = -1; - protected boolean pumpIgnoreDuplicates = false; - - /** nodeSize maximal size of node, larger node causes overflow and creation of new BTree node. Use large number for small keys, use small number for large keys.*/ - public BTreeSetMaker nodeSize(int nodeSize){ - this.nodeSize = nodeSize; - return this; - } - - - /** by default collection does not have counter, without counter updates are faster, but entire collection needs to be traversed to count items.*/ - public BTreeSetMaker counterEnable(){ - this.counter = true; - return this; - } - - /** keySerializer used to convert keys into/from binary form. */ - public BTreeSetMaker serializer(BTreeKeySerializer serializer){ - this.serializer = serializer; - return this; - } - - /** comparator used to sort keys. */ - public BTreeSetMaker comparator(Comparator comparator){ - this.comparator = comparator; - return this; - } - - public BTreeSetMaker pumpSource(Iterator source){ - this.pumpSource = source; - return this; - } - - /** - * If source iteretor contains an duplicate key, exception is thrown. - * This options will only use firts key and ignore any consequentive duplicates. - */ - public BTreeSetMaker pumpIgnoreDuplicates(){ - this.pumpIgnoreDuplicates = true; - return this; - } - - public BTreeSetMaker pumpPresort(int batchSize){ - this.pumpPresortBatchSize = batchSize; - return this; - } - - - public NavigableSet make(){ - return DB.this.createTreeSet(BTreeSetMaker.this); - } - - public NavigableSet makeOrGet(){ - synchronized (DB.this){ - //TODO add parameter check - return (NavigableSet) (catGet(name+".type")==null? - make():getTreeSet(name)); - } - } - - - - - /** creates set optimized for using `String` */ - public NavigableSet makeStringSet() { - serializer = BTreeKeySerializer.STRING; - return make(); - } - - /** creates set optimized for using zero or positive `Long` */ - public NavigableSet makeLongSet() { - serializer = BTreeKeySerializer.ZERO_OR_POSITIVE_LONG; - return make(); - } - - } - - - /** - * Opens existing or creates new B-linked-tree Map. - * This collection performs well under concurrent access. - * Only trade-off are deletes, which causes tree fragmentation. - * It is ordered and best suited for small keys and values. - * - * @param name of map - * @return map - */ - synchronized public BTreeMap getTreeMap(String name){ - checkNotClosed(); - BTreeMap ret = (BTreeMap) getFromWeakCollection(name); - if(ret!=null) return ret; - String type = catGet(name + ".type", null); - //$DELAY$ - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - new DB(e).getTreeMap("a"); - //$DELAY$ - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getTreeMap("a")); - } - return createTreeMap(name).make(); - - } - checkType(type, "TreeMap"); - - ret = new BTreeMap(engine, - (Long) catGet(name + ".rootRecidRef"), - catGet(name+".maxNodeSize",32), - catGet(name+".valuesOutsideNodes",false), - catGet(name+".counterRecid",0L), - catGet(name+".keySerializer",new BTreeKeySerializer.BasicKeySerializer(getDefaultSerializer(),Fun.COMPARATOR)), - catGet(name+".valueSerializer",getDefaultSerializer()), - catGet(name+".numberOfNodeMetas",0) - ); - //$DELAY$ - namedPut(name, ret); - return ret; - } - - /** - * Returns new builder for TreeMap with given name - * - * @param name of map to create - * @throws IllegalArgumentException if name is already used - * @return maker, call `.make()` to create map - */ - public BTreeMapMaker createTreeMap(String name){ - return new BTreeMapMaker(name); - } - - - synchronized protected BTreeMap createTreeMap(final BTreeMapMaker m){ - String name = m.name; - checkNameNotExists(name); - //$DELAY$ - if(m.comparator==null){ - m.comparator = Fun.COMPARATOR; - } - - m.keySerializer = fillNulls(m.keySerializer); - m.keySerializer = catPut(name+".keySerializer",m.keySerializer,new BTreeKeySerializer.BasicKeySerializer(getDefaultSerializer(),m.comparator)); - m.valueSerializer = catPut(name+".valueSerializer",m.valueSerializer,getDefaultSerializer()); - - if(m.pumpPresortBatchSize!=-1 && m.pumpSource!=null){ - Comparator presortComp = new Comparator() { - - @Override - public int compare(Object o1, Object o2) { - return - m.comparator.compare(m.pumpKeyExtractor.run(o1), m.pumpKeyExtractor.run(o2)); - } - }; - - m.pumpSource = Pump.sort(m.pumpSource,m.pumpIgnoreDuplicates, m.pumpPresortBatchSize, - presortComp,getDefaultSerializer()); - } - //$DELAY$ - long counterRecid = !m.counter ?0L:engine.put(0L, Serializer.LONG); - - long rootRecidRef; - if(m.pumpSource==null){ - rootRecidRef = BTreeMap.createRootRef(engine,m.keySerializer,m.valueSerializer,0); - }else{ - rootRecidRef = Pump.buildTreeMap( - (Iterator)m.pumpSource, - engine, - (Fun.Function1)m.pumpKeyExtractor, - (Fun.Function1)m.pumpValueExtractor, - m.pumpIgnoreDuplicates,m.nodeSize, - m.valuesOutsideNodes, - counterRecid, - m.keySerializer, - (Serializer)m.valueSerializer); - } - //$DELAY$ - BTreeMap ret = new BTreeMap(engine, - catPut(name+".rootRecidRef", rootRecidRef), - catPut(name+".maxNodeSize",m.nodeSize), - catPut(name+".valuesOutsideNodes",m.valuesOutsideNodes), - catPut(name+".counterRecid",counterRecid), - m.keySerializer, - (Serializer)m.valueSerializer, - catPut(m.name+".numberOfNodeMetas",0) - ); - //$DELAY$ - catalog.put(name + ".type", "TreeMap"); - namedPut(name, ret); - return ret; - } - - /** - * Replace nulls in tuple serializers with default (Comparable) values - * - * @param keySerializer with nulls - * @return keySerializers which does not contain any nulls - */ - protected BTreeKeySerializer fillNulls(BTreeKeySerializer keySerializer) { - if(keySerializer==null) - return null; - if(keySerializer instanceof BTreeKeySerializer.ArrayKeySerializer) { - BTreeKeySerializer.ArrayKeySerializer k = (BTreeKeySerializer.ArrayKeySerializer) keySerializer; - - Serializer[] serializers = new Serializer[k.tsize]; - Comparator[] comparators = new Comparator[k.tsize]; - //$DELAY$ - for (int i = 0; i < k.tsize; i++) { - serializers[i] = k.serializers[i] != null && k.serializers[i]!=Serializer.BASIC ? k.serializers[i] : getDefaultSerializer(); - comparators[i] = k.comparators[i] != null ? k.comparators[i] : Fun.COMPARATOR; - } - //$DELAY$ - return new BTreeKeySerializer.ArrayKeySerializer(comparators, serializers); - } - //$DELAY$ - return keySerializer; - } - - - /** - * Get Name Catalog. - * It is metatable which contains information about named collections and records. - * Each collection constructor takes number of parameters, this map contains those parameters. - * - * _Note:_ Do not modify this map, unless you know what you are doing! - * - * @return Name Catalog - */ - public SortedMap getCatalog(){ - return catalog; - } - - - /** - * Opens existing or creates new B-linked-tree Set. - * - * @param name of set - * @return set - */ - synchronized public NavigableSet getTreeSet(String name){ - checkNotClosed(); - NavigableSet ret = (NavigableSet) getFromWeakCollection(name); - if(ret!=null) return ret; - String type = catGet(name + ".type", null); - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - new DB(e).getTreeSet("a"); - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getTreeSet("a")); - } - //$DELAY$ - return createTreeSet(name).make(); - - } - checkType(type, "TreeSet"); - //$DELAY$ - ret = new BTreeMap(engine, - (Long) catGet(name+".rootRecidRef"), - catGet(name+".maxNodeSize",32), - false, - catGet(name+".counterRecid",0L), - catGet(name+".keySerializer",new BTreeKeySerializer.BasicKeySerializer(getDefaultSerializer(),Fun.COMPARATOR)), - null, - catGet(name+".numberOfNodeMetas",0) - ).keySet(); - //$DELAY$ - namedPut(name, ret); - return ret; - - } - - /** - * Creates new TreeSet. - * @param name of set to create - * @throws IllegalArgumentException if name is already used - * @return maker used to construct set - */ - synchronized public BTreeSetMaker createTreeSet(String name){ - return new BTreeSetMaker(name); - } - - synchronized public NavigableSet createTreeSet(BTreeSetMaker m){ - checkNameNotExists(m.name); - if(m.comparator==null){ - m.comparator = Fun.COMPARATOR; - } - //$DELAY$ - m.serializer = fillNulls(m.serializer); - m.serializer = catPut(m.name+".keySerializer",m.serializer,new BTreeKeySerializer.BasicKeySerializer(getDefaultSerializer(),m.comparator)); - - if(m.pumpPresortBatchSize!=-1){ - m.pumpSource = Pump.sort(m.pumpSource,m.pumpIgnoreDuplicates, m.pumpPresortBatchSize,Collections.reverseOrder(m.comparator),getDefaultSerializer()); - } - - long counterRecid = !m.counter ?0L:engine.put(0L, Serializer.LONG); - long rootRecidRef; - //$DELAY$ - if(m.pumpSource==null){ - rootRecidRef = BTreeMap.createRootRef(engine,m.serializer,null,0); - }else{ - rootRecidRef = Pump.buildTreeMap( - (Iterator)m.pumpSource, - engine, - Fun.extractNoTransform(), - null, - m.pumpIgnoreDuplicates, - m.nodeSize, - false, - counterRecid, - m.serializer, - null); - } - //$DELAY$ - NavigableSet ret = new BTreeMap( - engine, - catPut(m.name+".rootRecidRef", rootRecidRef), - catPut(m.name+".maxNodeSize",m.nodeSize), - false, - catPut(m.name+".counterRecid",counterRecid), - m.serializer, - null, - catPut(m.name+".numberOfNodeMetas",0) - ).keySet(); - //$DELAY$ - catalog.put(m.name + ".type", "TreeSet"); - namedPut(m.name, ret); - return ret; - } - - synchronized public BlockingQueue getQueue(String name) { - checkNotClosed(); - Queues.Queue ret = (Queues.Queue) getFromWeakCollection(name); - if(ret!=null) return ret; - String type = catGet(name + ".type", null); - //$DELAY$ - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - new DB(e).getQueue("a"); - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getQueue("a")); - } - //$DELAY$ - return createQueue(name,null,true); - } - checkType(type, "Queue"); - //$DELAY$ - ret = new Queues.Queue(engine, - (Serializer) catGet(name+".serializer",getDefaultSerializer()), - (Long)catGet(name+".headRecid"), - (Long)catGet(name+".tailRecid"), - (Boolean)catGet(name+".useLocks") - ); - //$DELAY$ - namedPut(name, ret); - return ret; - } - - synchronized public BlockingQueue createQueue(String name, Serializer serializer, boolean useLocks) { - checkNameNotExists(name); - - long node = engine.put(Queues.SimpleQueue.Node.EMPTY, new Queues.SimpleQueue.NodeSerializer(serializer)); - long headRecid = engine.put(node, Serializer.LONG); - long tailRecid = engine.put(node, Serializer.LONG); - //$DELAY$ - Queues.Queue ret = new Queues.Queue(engine, - catPut(name+".serializer",serializer,getDefaultSerializer()), - catPut(name+".headRecid",headRecid), - catPut(name+".tailRecid",tailRecid), - catPut(name+".useLocks",useLocks) - ); - catalog.put(name + ".type", "Queue"); - //$DELAY$ - namedPut(name, ret); - return ret; - - } - - - synchronized public BlockingQueue getStack(String name) { - checkNotClosed(); - Queues.Stack ret = (Queues.Stack) getFromWeakCollection(name); - if(ret!=null) return ret; - //$DELAY$ - String type = catGet(name + ".type", null); - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - //$DELAY$ - new DB(e).getStack("a"); //TODO WFT? - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getStack("a")); - } - return createStack(name,null,true); - } - //$DELAY$ - checkType(type, "Stack"); - - ret = new Queues.Stack(engine, - (Serializer) catGet(name+".serializer",getDefaultSerializer()), - (Long)catGet(name+".headRecid"), - (Boolean)catGet(name+".useLocks") - ); - //$DELAY$ - namedPut(name, ret); - //$DELAY$ - return ret; - } - - - - synchronized public BlockingQueue createStack(String name, Serializer serializer, boolean useLocks) { - checkNameNotExists(name); - - long node = engine.put(Queues.SimpleQueue.Node.EMPTY, new Queues.SimpleQueue.NodeSerializer(serializer)); - long headRecid = engine.put(node, Serializer.LONG); - //$DELAY$ - Queues.Stack ret = new Queues.Stack(engine, - catPut(name+".serializer",serializer,getDefaultSerializer()), - catPut(name+".headRecid",headRecid), - catPut(name+".useLocks",useLocks) - ); - //$DELAY$ - catalog.put(name + ".type", "Stack"); - namedPut(name, ret); - return ret; - } - - - synchronized public BlockingQueue getCircularQueue(String name) { - checkNotClosed(); - BlockingQueue ret = (BlockingQueue) getFromWeakCollection(name); - if(ret!=null) return ret; - String type = catGet(name + ".type", null); - //$DELAY$ - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - new DB(e).getCircularQueue("a"); - //$DELAY$ - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getCircularQueue("a")); - } - return createCircularQueue(name,null, 1024); - } - - checkType(type, "CircularQueue"); - - ret = new Queues.CircularQueue(engine, - (Serializer) catGet(name+".serializer",getDefaultSerializer()), - (Long)catGet(name+".headRecid"), - (Long)catGet(name+".headInsertRecid"), - (Long)catGet(name+".size") - ); - //$DELAY$ - - namedPut(name, ret); - return ret; - } - - - - synchronized public BlockingQueue createCircularQueue(String name, Serializer serializer, long size) { - checkNameNotExists(name); - if(serializer==null) serializer = getDefaultSerializer(); - -// long headerRecid = engine.put(0L, Serializer.LONG); - //insert N Nodes empty nodes into a circle - long prevRecid = 0; - long firstRecid = 0; - //$DELAY$ - Serializer> nodeSer = new Queues.SimpleQueue.NodeSerializer(serializer); - for(long i=0;i n = new Queues.SimpleQueue.Node(prevRecid, null); - prevRecid = engine.put(n, nodeSer); - if(firstRecid==0) firstRecid = prevRecid; - } - //update first node to point to last recid - engine.update(firstRecid, new Queues.SimpleQueue.Node(prevRecid, null), nodeSer ); - - long headRecid = engine.put(prevRecid, Serializer.LONG); - long headInsertRecid = engine.put(prevRecid, Serializer.LONG); - //$DELAY$ - - - Queues.CircularQueue ret = new Queues.CircularQueue(engine, - catPut(name+".serializer",serializer), - catPut(name+".headRecid",headRecid), - catPut(name+".headInsertRecid",headInsertRecid), - catPut(name+".size",size) - ); - //$DELAY$ - catalog.put(name + ".type", "CircularQueue"); - namedPut(name, ret); - return ret; - } - - synchronized public Atomic.Long createAtomicLong(String name, long initValue){ - checkNameNotExists(name); - long recid = engine.put(initValue,Serializer.LONG); - Atomic.Long ret = new Atomic.Long(engine, - catPut(name+".recid",recid) - ); - //$DELAY$ - catalog.put(name + ".type", "AtomicLong"); - namedPut(name, ret); - return ret; - - } - - - synchronized public Atomic.Long getAtomicLong(String name){ - checkNotClosed(); - Atomic.Long ret = (Atomic.Long) getFromWeakCollection(name); - if(ret!=null) return ret; - //$DELAY$ - String type = catGet(name + ".type", null); - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - new DB(e).getAtomicLong("a"); - //$DELAY$ - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getAtomicLong("a")); - } - return createAtomicLong(name,0L); - } - checkType(type, "AtomicLong"); - //$DELAY$ - ret = new Atomic.Long(engine, (Long) catGet(name+".recid")); - namedPut(name, ret); - return ret; - } - - - - synchronized public Atomic.Integer createAtomicInteger(String name, int initValue){ - checkNameNotExists(name); - long recid = engine.put(initValue,Serializer.INTEGER); - Atomic.Integer ret = new Atomic.Integer(engine, - catPut(name+".recid",recid) - ); - //$DELAY$ - catalog.put(name + ".type", "AtomicInteger"); - namedPut(name, ret); - return ret; - - } - - - synchronized public Atomic.Integer getAtomicInteger(String name){ - checkNotClosed(); - Atomic.Integer ret = (Atomic.Integer) getFromWeakCollection(name); - if(ret!=null) return ret; - //$DELAY$ - String type = catGet(name + ".type", null); - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - new DB(e).getAtomicInteger("a"); - //$DELAY$ - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getAtomicInteger("a")); - } - return createAtomicInteger(name, 0); - } - checkType(type, "AtomicInteger"); - - ret = new Atomic.Integer(engine, (Long) catGet(name+".recid")); - namedPut(name, ret); - return ret; - } - - - - synchronized public Atomic.Boolean createAtomicBoolean(String name, boolean initValue){ - checkNameNotExists(name); - long recid = engine.put(initValue,Serializer.BOOLEAN); - //$DELAY$ - Atomic.Boolean ret = new Atomic.Boolean(engine, - catPut(name+".recid",recid) - ); - catalog.put(name + ".type", "AtomicBoolean"); - //$DELAY$ - namedPut(name, ret); - return ret; - - } - - - synchronized public Atomic.Boolean getAtomicBoolean(String name){ - checkNotClosed(); - Atomic.Boolean ret = (Atomic.Boolean) getFromWeakCollection(name); - if(ret!=null) return ret; - //$DELAY$ - String type = catGet(name + ".type", null); - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - new DB(e).getAtomicBoolean("a"); - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getAtomicBoolean("a")); - } - //$DELAY$ - return createAtomicBoolean(name, false); - } - checkType(type, "AtomicBoolean"); - //$DELAY$ - ret = new Atomic.Boolean(engine, (Long) catGet(name+".recid")); - namedPut(name, ret); - return ret; - } - - public void checkShouldCreate(String name) { - if(strictDBGet) throw new NoSuchElementException("No record with this name was found: "+name); - } - - - synchronized public Atomic.String createAtomicString(String name, String initValue){ - checkNameNotExists(name); - if(initValue==null) throw new IllegalArgumentException("initValue may not be null"); - long recid = engine.put(initValue,Serializer.STRING_NOSIZE); - //$DELAY$ - Atomic.String ret = new Atomic.String(engine, - catPut(name+".recid",recid) - ); - //$DELAY$ - catalog.put(name + ".type", "AtomicString"); - namedPut(name, ret); - return ret; - - } - - - synchronized public Atomic.String getAtomicString(String name){ - checkNotClosed(); - Atomic.String ret = (Atomic.String) getFromWeakCollection(name); - if(ret!=null) return ret; - String type = catGet(name + ".type", null); - //$DELAY$ - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - new DB(e).getAtomicString("a"); - //$DELAY$ - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getAtomicString("a")); - } - return createAtomicString(name, ""); - } - checkType(type, "AtomicString"); - - ret = new Atomic.String(engine, (Long) catGet(name+".recid")); - namedPut(name, ret); - return ret; - } - - synchronized public Atomic.Var createAtomicVar(String name, E initValue, Serializer serializer){ - checkNameNotExists(name); - if(serializer==null) serializer=getDefaultSerializer(); - long recid = engine.put(initValue,serializer); - //$DELAY$ - Atomic.Var ret = new Atomic.Var(engine, - catPut(name+".recid",recid), - catPut(name+".serializer",serializer) - ); - //$DELAY$ - catalog.put(name + ".type", "AtomicVar"); - namedPut(name, ret); - return ret; - - } - - - synchronized public Atomic.Var getAtomicVar(String name){ - checkNotClosed(); - - Atomic.Var ret = (Atomic.Var) getFromWeakCollection(name); - if(ret!=null) return ret; - String type = catGet(name + ".type", null); - if(type==null){ - checkShouldCreate(name); - if(engine.isReadOnly()){ - Engine e = new StoreHeap(); - new DB(e).getAtomicVar("a"); - return namedPut(name, - new DB(new EngineWrapper.ReadOnlyEngine(e)).getAtomicVar("a")); - } - //$DELAY$ - return createAtomicVar(name, null, getDefaultSerializer()); - } - checkType(type, "AtomicVar"); - - ret = new Atomic.Var(engine, (Long) catGet(name+".recid"), (Serializer) catGet(name+".serializer")); - namedPut(name, ret); - return ret; - } - - /** return record with given name or null if name does not exist*/ - synchronized public E get(String name){ - //$DELAY$ - String type = catGet(name+".type"); - if(type==null) return null; - if("HashMap".equals(type)) return (E) getHashMap(name); - if("HashSet".equals(type)) return (E) getHashSet(name); - if("TreeMap".equals(type)) return (E) getTreeMap(name); - if("TreeSet".equals(type)) return (E) getTreeSet(name); - if("AtomicBoolean".equals(type)) return (E) getAtomicBoolean(name); - if("AtomicInteger".equals(type)) return (E) getAtomicInteger(name); - if("AtomicLong".equals(type)) return (E) getAtomicLong(name); - if("AtomicString".equals(type)) return (E) getAtomicString(name); - if("AtomicVar".equals(type)) return (E) getAtomicVar(name); - if("Queue".equals(type)) return (E) getQueue(name); - if("Stack".equals(type)) return (E) getStack(name); - if("CircularQueue".equals(type)) return (E) getCircularQueue(name); - throw new AssertionError("Unknown type: "+name); - } - - synchronized public boolean exists(String name){ - return catGet(name+".type")!=null; - } - - /** delete record/collection with given name*/ - synchronized public void delete(String name){ - //$DELAY$ - Object r = get(name); - if(r instanceof Atomic.Boolean){ - engine.delete(((Atomic.Boolean)r).recid, Serializer.BOOLEAN); - }else if(r instanceof Atomic.Integer){ - engine.delete(((Atomic.Integer)r).recid, Serializer.INTEGER); - }else if(r instanceof Atomic.Long){ - engine.delete(((Atomic.Long)r).recid, Serializer.LONG); - }else if(r instanceof Atomic.String){ - engine.delete(((Atomic.String)r).recid, Serializer.STRING_NOSIZE); - }else if(r instanceof Atomic.Var){ - engine.delete(((Atomic.Var)r).recid, ((Atomic.Var)r).serializer); - }else if(r instanceof Queue){ - //drain queue - Queue q = (Queue) r; - while(q.poll()!=null){ - //do nothing - } - }else if(r instanceof HTreeMap || r instanceof HTreeMap.KeySet){ - HTreeMap m = (r instanceof HTreeMap)? (HTreeMap) r : ((HTreeMap.KeySet)r).parent(); - m.clear(); - //$DELAY$ - //delete segments - for(long segmentRecid:m.segmentRecids){ - engine.delete(segmentRecid, HTreeMap.DIR_SERIALIZER); - } - }else if(r instanceof BTreeMap || r instanceof BTreeMap.KeySet){ - BTreeMap m = (r instanceof BTreeMap)? (BTreeMap) r : (BTreeMap) ((BTreeMap.KeySet) r).m; - //$DELAY$ - //TODO on BTreeMap recursively delete all nodes - m.clear(); - - if(m.counter!=null) - engine.delete(m.counter.recid,Serializer.LONG); - } - - for(String n:catalog.keySet()){ - if(!n.startsWith(name)) - continue; - String suffix = n.substring(name.length()); - if(suffix.charAt(0)=='.' && suffix.length()>1 && !suffix.substring(1).contains(".")) - catalog.remove(n); - } - namesInstanciated.remove(name); - namesLookup.remove(new IdentityWrapper(r)); - } - - - /** - * return map of all named collections/records - */ - synchronized public Map getAll(){ - TreeMap ret= new TreeMap(); - //$DELAY$ - for(String name:catalog.keySet()){ - if(!name.endsWith(".type")) continue; - //$DELAY$ - name = name.substring(0,name.length()-5); - ret.put(name,get(name)); - } - - return Collections.unmodifiableMap(ret); - } - - - /** rename named record into newName - * - * @param oldName current name of record/collection - * @param newName new name of record/collection - * @throws NoSuchElementException if oldName does not exist - */ - synchronized public void rename(String oldName, String newName){ - if(oldName.equals(newName)) return; - //$DELAY$ - Map sub = catalog.tailMap(oldName); - List toRemove = new ArrayList(); - //$DELAY$ - for(String param:sub.keySet()){ - if(!param.startsWith(oldName)) break; - - String suffix = param.substring(oldName.length()); - catalog.put(newName+suffix, catalog.get(param)); - toRemove.add(param); - } - if(toRemove.isEmpty()) throw new NoSuchElementException("Could not rename, name does not exist: "+oldName); - //$DELAY$ - WeakReference old = namesInstanciated.remove(oldName); - if(old!=null){ - Object old2 = old.get(); - if(old2!=null){ - namesLookup.remove(new IdentityWrapper(old2)); - namedPut(newName,old2); - } - } - for(String param:toRemove) catalog.remove(param); - } - - - /** - * Checks that object with given name does not exist yet. - * @param name to check - * @throws IllegalArgumentException if name is already used - */ - public void checkNameNotExists(String name) { - if(catalog.get(name+".type")!=null) - throw new IllegalArgumentException("Name already used: "+name); - } - - - /** - * Closes database. - * All other methods will throw 'IllegalAccessError' after this method was called. - *

- * !! it is necessary to call this method before JVM exits!! - */ - synchronized public void close(){ - if(engine == null) return; - for(WeakReference r:namesInstanciated.values()){ - Object rr = r.get(); - if(rr !=null && rr instanceof Closeable) - try { - ((Closeable)rr).close(); - } catch (IOException e) { - throw new IOError(e); - } - } - engine.close(); - //dereference db to prevent memory leaks - engine = EngineWrapper.CLOSED; - namesInstanciated = Collections.unmodifiableMap(new HashMap()); - namesLookup = Collections.unmodifiableMap(new HashMap()); - } - - /** - * All collections are weakly referenced to prevent two instances of the same collection in memory. - * This is mainly for locking, two instances of the same lock would not simply work. - */ - synchronized public Object getFromWeakCollection(String name){ - WeakReference r = namesInstanciated.get(name); - //$DELAY$ - if(r==null) return null; - //$DELAY$ - Object o = r.get(); - if(o==null) namesInstanciated.remove(name); - return o; - } - - - - public void checkNotClosed() { - if(engine == null) throw new IllegalAccessError("DB was already closed"); - } - - /** - * @return true if DB is closed and can no longer be used - */ - public synchronized boolean isClosed(){ - return engine == null || engine.isClosed(); - } - - /** - * Commit changes made on collections loaded by this DB - * - * @see org.mapdb.Engine#commit() - */ - synchronized public void commit() { - checkNotClosed(); - engine.commit(); - } - - /** - * Rollback changes made on collections loaded by this DB - * - * @see org.mapdb.Engine#rollback() - */ - synchronized public void rollback() { - checkNotClosed(); - engine.rollback(); - } - - /** - * Perform storage maintenance. - * Typically compact underlying storage and reclaim unused space. - *

- * NOTE: MapDB does not have smart defragmentation algorithms. So compaction usually recreates entire - * store from scratch. This may require additional disk space. - */ - synchronized public void compact(){ - engine.compact(); - } - - - /** - * Make readonly snapshot view of DB and all of its collection - * Collections loaded by this instance are not affected (are still mutable). - * You have to load new collections from DB returned by this method - * - * @return readonly snapshot view - */ - synchronized public DB snapshot(){ - Engine snapshot = TxEngine.createSnapshotFor(engine); - return new DB (snapshot); - } - - /** - * @return default serializer used in this DB, it handles POJO and other stuff. - */ - public Serializer getDefaultSerializer() { - return engine.getSerializerPojo(); - } - - /** - * @return underlying engine which takes care of persistence for this DB. - */ - public Engine getEngine() { - return engine; - } - - public void checkType(String type, String expected) { - //$DELAY$ - if(!expected.equals(type)) throw new IllegalArgumentException("Wrong type: "+type); - } - - -} diff --git a/src/main/java/org/mapdb/DBException.java b/src/main/java/org/mapdb/DBException.java new file mode 100644 index 000000000..fc9b3266f --- /dev/null +++ b/src/main/java/org/mapdb/DBException.java @@ -0,0 +1,102 @@ +package org.mapdb; + + +public class DBException extends RuntimeException { + + public DBException(Exception cause){ + super(cause); + } + + public DBException(String msg){ + super(msg); + } + + public DBException(String msg, Exception cause){ + super(msg,cause); + } + + public static class RecordNotFound extends DBException{ + public RecordNotFound(){ + super("record not found"); + } + } + + + + public static class StoreReentry extends DBException { + public StoreReentry() { + super("repeated call to Store method"); + } + } + + public static class FileLocked extends DBException { + public FileLocked() { + super("file locked"); + } + } + + public static class PreallocRecordAccess extends DBException{ + public PreallocRecordAccess(){ + super("preallocated record accessed"); + } + } + + public static class StoreClosed extends DBException{ + public StoreClosed(){ + super("store closed"); + } + } + + + public static class DataCorruption extends DBException{ + public DataCorruption(){ + super("data corruption"); + } + + public DataCorruption(String msg) { + super(msg); + } + } + + public static class SerializationError extends DBException{ + public SerializationError(Exception e){ + super(e); + } + } + + public static class WrongConfig extends DBException { + + public WrongConfig(String msg) { + super(msg); + } + } + + public static class WrongSerializer extends WrongConfig{ + public WrongSerializer(){ + super("wrong serializer used"); + } + } + + + public static class PointerChecksumBroken extends DataCorruption{ + + } + + public static class TODO extends DBException{ + + public TODO() { + super("not implemented yet"); + } + + public TODO(String msg) { + super(msg); + } + } + + public static class RecordNotPreallocated extends DBException { + + public RecordNotPreallocated() { + super("Record was not preallocated"); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/mapdb/DBMaker.java b/src/main/java/org/mapdb/DBMaker.java deleted file mode 100644 index 19acbcd4b..000000000 --- a/src/main/java/org/mapdb/DBMaker.java +++ /dev/null @@ -1,1007 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import org.mapdb.EngineWrapper.ReadOnlyEngine; - -import java.io.File; -import java.io.IOError; -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.*; - -/** - * A builder class for creating and opening a database. - * - * @author Jan Kotek - */ -public class DBMaker{ - - protected final String TRUE = "true"; - - protected Fun.RecordCondition cacheCondition; - protected Fun.ThreadFactory threadFactory = Fun.ThreadFactory.BASIC; - - protected interface Keys{ - String cache = "cache"; - String cacheSize = "cacheSize"; - String cache_disable = "disable"; - String cache_hashTable = "hashTable"; - String cache_hardRef = "hardRef"; - String cache_softRef = "softRef"; - String cache_weakRef = "weakRef"; - String cache_lru = "lru"; - - String file = "file"; - - String volume = "volume"; - String volume_raf = "raf"; - String volume_mmapfPartial = "mmapfPartial"; - String volume_mmapfIfSupported = "mmapfIfSupported"; - String volume_mmapf = "mmapf"; - String volume_byteBuffer = "byteBuffer"; - String volume_directByteBuffer = "directByteBuffer"; - - - String store = "store"; - String store_direct = "direct"; - String store_wal = "wal"; - String store_append = "append"; - String store_heap = "heap"; - - String transactionDisable = "transactionDisable"; - - String asyncWrite = "asyncWrite"; - String asyncWriteFlushDelay = "asyncWriteFlushDelay"; - String asyncWriteQueueSize = "asyncWriteQueueSize"; - - String deleteFilesAfterClose = "deleteFilesAfterClose"; - String closeOnJvmShutdown = "closeOnJvmShutdown"; - - String readOnly = "readOnly"; - - String compression = "compression"; - String compression_lzf = "lzf"; - - String encryptionKey = "encryptionKey"; - String encryption = "encryption"; - String encryption_xtea = "xtea"; - - String checksum = "checksum"; - - String freeSpaceReclaimQ = "freeSpaceReclaimQ"; - String commitFileSyncDisable = "commitFileSyncDisable"; - - String snapshots = "snapshots"; - - String strictDBGet = "strictDBGet"; - - String sizeLimit = "sizeLimit"; - - String fullTx = "fullTx"; - } - - protected Properties props = new Properties(); - - /** use static factory methods, or make subclass */ - protected DBMaker(){} - - protected DBMaker(File file) { - props.setProperty(Keys.file, file.getPath()); - } - - /** - * Creates new in-memory database which stores all data on heap without serialization. - * This mode should be very fast, but data will affect Garbage Collector the same way as traditional Java Collections. - */ - public static DBMaker newHeapDB(){ - return new DBMaker()._newHeapDB(); - } - - public DBMaker _newHeapDB(){ - props.setProperty(Keys.store,Keys.store_heap); - return this; - } - - - /** Creates new in-memory database. Changes are lost after JVM exits. - *

- * This will use HEAP memory so Garbage Collector is affected. - */ - public static DBMaker newMemoryDB(){ - return new DBMaker()._newMemoryDB(); - } - - public DBMaker _newMemoryDB(){ - props.setProperty(Keys.volume,Keys.volume_byteBuffer); - return this; - } - - /** Creates new in-memory database. Changes are lost after JVM exits. - *

- * This will use DirectByteBuffer outside of HEAP, so Garbage Collector is not affected - */ - public static DBMaker newMemoryDirectDB(){ - return new DBMaker()._newMemoryDirectDB(); - } - - public DBMaker _newMemoryDirectDB() { - props.setProperty(Keys.volume,Keys.volume_directByteBuffer); - return this; - } - - - - /** - * Creates or open append-only database stored in file. - * This database uses format other than usual file db - * - * @param file - * @return maker - */ - public static DBMaker newAppendFileDB(File file) { - return new DBMaker()._newAppendFileDB(file); - } - - public DBMaker _newAppendFileDB(File file) { - props.setProperty(Keys.file, file.getPath()); - props.setProperty(Keys.store, Keys.store_append); - return this; - } - - - /** - * Create new BTreeMap backed by temporary file storage. - * This is quick way to create 'throw away' collection. - * - *

Storage is created in temp folder and deleted on JVM shutdown - */ - public static BTreeMap newTempTreeMap(){ - return newTempFileDB() - .deleteFilesAfterClose() - .closeOnJvmShutdown() - .transactionDisable() - .make() - .getTreeMap("temp"); - } - - /** - * Create new HTreeMap backed by temporary file storage. - * This is quick way to create 'throw away' collection. - * - *

Storage is created in temp folder and deleted on JVM shutdown - */ - public static HTreeMap newTempHashMap(){ - return newTempFileDB() - .deleteFilesAfterClose() - .closeOnJvmShutdown() - .transactionDisable() - .make() - .getHashMap("temp"); - } - - /** - * Create new TreeSet backed by temporary file storage. - * This is quick way to create 'throw away' collection. - * - *

Storage is created in temp folder and deleted on JVM shutdown - */ - public static NavigableSet newTempTreeSet(){ - return newTempFileDB() - .deleteFilesAfterClose() - .closeOnJvmShutdown() - .transactionDisable() - .make() - .getTreeSet("temp"); - } - - /** - * Create new HashSet backed by temporary file storage. - * This is quick way to create 'throw away' collection. - *

- * Storage is created in temp folder and deleted on JVM shutdown - */ - public static Set newTempHashSet(){ - return newTempFileDB() - .deleteFilesAfterClose() - .closeOnJvmShutdown() - .transactionDisable() - .make() - .getHashSet("temp"); - } - - /** - * Creates new database in temporary folder. - */ - public static DBMaker newTempFileDB() { - try { - return newFileDB(File.createTempFile("mapdb-temp","db")); - } catch (IOException e) { - throw new IOError(e); - } - } - - /** - * Creates new off-heap cache with maximal size in GBs. - * Entries are removed from cache in most-recently-used fashion - * if store becomes too big. - * - * This method uses off-heap direct ByteBuffers. See {@link java.nio.ByteBuffer#allocateDirect(int)} - * - * @param size maximal size of off-heap store in gigabytes. - * @return map - */ - public static HTreeMap newCacheDirect(double size){ - return DBMaker - .newMemoryDirectDB() - .transactionDisable() - .make() - .createHashMap("cache") - .expireStoreSize(size) - .counterEnable() - .make(); - } - - /** - * Creates new cache with maximal size in GBs. - * Entries are removed from cache in most-recently-used fashion - * if store becomes too big. - * - * This cache uses on-heap `byte[]`, but does not affect GC since objects are serialized into binary form. - * This method uses ByteBuffers backed by on-heap byte[]. See {@link java.nio.ByteBuffer#allocate(int)} - * - * @param size maximal size of off-heap store in gigabytes. - * @return map - */ - public static HTreeMap newCache(double size){ - return DBMaker - .newMemoryDB() - .transactionDisable() - .make() - .createHashMap("cache") - .expireStoreSize(size) - .counterEnable() - .make(); - } - - - /** Creates or open database stored in file. */ - public static DBMaker newFileDB(File file){ - return new DBMaker(file); - } - - public DBMaker _newFileDB(File file){ - props.setProperty(Keys.file, file.getPath()); - return this; - } - - - /** - * Transaction journal is enabled by default - * You must call DB.commit() to save your changes. - * It is possible to disable transaction journal for better write performance - * In this case all integrity checks are sacrificed for faster speed. - *

- * If transaction journal is disabled, all changes are written DIRECTLY into store. - * You must call DB.close() method before exit, - * otherwise your store WILL BE CORRUPTED - * - * - * @return this builder - */ - public DBMaker transactionDisable(){ - props.put(Keys.transactionDisable,TRUE); - return this; - } - - /** - * Install callback condition, which decides if some record is to be included in cache. - * Condition should return `true` for every record which should be included - * - * This could be for example useful to include only BTree Directory Nodes and leave values and Leaf nodes outside of cache. - * - * !!! Warning:!!! - * - * Cache requires **consistent** true or false. Failing to do so will result in inconsitent cache and possible data corruption. - - * Condition is also executed several times, so it must be very fast - * - * You should only use very simple logic such as `value instanceof SomeClass`. - * - * @return this builder - */ - public DBMaker cacheCondition(Fun.RecordCondition cacheCondition){ - this.cacheCondition = cacheCondition; - return this; - } - - /** - - /** - * Instance cache is enabled by default. - * This greatly decreases serialization overhead and improves performance. - * Call this method to disable instance cache, so an object will always be deserialized. - *

- * This may workaround some problems - * - * @return this builder - */ - public DBMaker cacheDisable(){ - props.put(Keys.cache,Keys.cache_disable); - return this; - } - - /** - * Enables unbounded hard reference cache. - * This cache is good if you have lot of available memory. - *

- * All fetched records are added to HashMap and stored with hard reference. - * To prevent OutOfMemoryExceptions MapDB monitors free memory, - * if it is bellow 25% cache is cleared. - * - * @return this builder - */ - public DBMaker cacheHardRefEnable(){ - props.put(Keys.cache,Keys.cache_hardRef); - return this; - } - - - /** - * Enables unbounded cache which uses WeakReference. - * Items are removed from cache by Garbage Collector - * - * @return this builder - */ - public DBMaker cacheWeakRefEnable(){ - props.put(Keys.cache,Keys.cache_weakRef); - return this; - } - - /** - * Enables unbounded cache which uses SoftReference. - * Items are removed from cache by Garbage Collector - * - * @return this builder - */ - public DBMaker cacheSoftRefEnable(){ - props.put(Keys.cache,Keys.cache_softRef); - return this; - } - - /** - * Enables Least Recently Used cache. It is fixed size cache and it removes less used items to make space. - * - * @return this builder - */ - public DBMaker cacheLRUEnable(){ - props.put(Keys.cache,Keys.cache_lru); - return this; - } - /** - * Enables Memory Mapped Files, much faster storage option. However on 32bit JVM this mode could corrupt - * your DB thanks to 4GB memory addressing limit. - * - * You may experience `java.lang.OutOfMemoryError: Map failed` exception on 32bit JVM, if you enable this - * mode. - */ - public DBMaker mmapFileEnable() { - assertNotInMemoryVolume(); - props.setProperty(Keys.volume,Keys.volume_mmapf); - return this; - } - - - /** - * Keeps small-frequently-used part of storage files memory mapped, but main area is accessed using Random Access File. - * - * This mode is good performance compromise between Memory Mapped Files and old slow Random Access Files. - * - * Index file is typically 5% of storage. It contains small frequently read values, - * which is where memory mapped file excel. - * - * With this mode you will experience `java.lang.OutOfMemoryError: Map failed` exceptions on 32bit JVMs - * eventually. But storage size limit is pushed to somewhere around 40GB. - * - */ - public DBMaker mmapFileEnablePartial() { - assertNotInMemoryVolume(); - props.setProperty(Keys.volume,Keys.volume_mmapfPartial); - return this; - } - - private void assertNotInMemoryVolume() { - if(Keys.volume_byteBuffer.equals(props.getProperty(Keys.volume)) || - Keys.volume_directByteBuffer.equals(props.getProperty(Keys.volume))) - throw new IllegalArgumentException("Can not enable mmap file for in-memory store"); - } - - /** - * Enable Memory Mapped Files only if current JVM supports it (is 64bit). - */ - public DBMaker mmapFileEnableIfSupported() { - assertNotInMemoryVolume(); - props.setProperty(Keys.volume,Keys.volume_mmapfIfSupported); - return this; - } - - /** - * Set cache size. Interpretations depends on cache type. - * For fixed size caches (such as FixedHashTable cache) it is maximal number of items in cache. - *

- * For unbounded caches (such as HardRef cache) it is initial capacity of underlying table (HashMap). - *

- * Default cache size is 32768. - * - * @param cacheSize new cache size - * @return this builder - */ - public DBMaker cacheSize(int cacheSize){ - props.setProperty(Keys.cacheSize,""+cacheSize); - return this; - } - - /** - * MapDB supports snapshots. `TxEngine` requires additional locking which has small overhead when not used. - * Snapshots are disabled by default. This option switches the snapshots on. - * - * @return this builder - */ - public DBMaker snapshotEnable(){ - props.setProperty(Keys.snapshots,TRUE); - return this; - } - - - /** - * Enables mode where all modifications are queued and written into disk on Background Writer Thread. - * So all modifications are performed in asynchronous mode and do not block. - * - *

- * Enabling this mode might increase performance for single threaded apps. - * - * @return this builder - */ - public DBMaker asyncWriteEnable(){ - props.setProperty(Keys.asyncWrite,TRUE); - return this; - } - - - - /** - * Set flush interval for write cache, by default is 0 - *

- * When BTreeMap is constructed from ordered set, tree node size is increasing linearly with each - * item added. Each time new key is added to tree node, its size changes and - * storage needs to find new place. So constructing BTreeMap from ordered set leads to large - * store fragmentation. - *

- * Setting flush interval is workaround as BTreeMap node is always updated in memory (write cache) - * and only final version of node is stored on disk. - * - * - * @param delay flush write cache every N miliseconds - * @return this builder - */ - public DBMaker asyncWriteFlushDelay(int delay){ - props.setProperty(Keys.asyncWriteFlushDelay,""+delay); - return this; - } - - /** - * Set size of async Write Queue. Default size is 32 000 - *

- * Using too large queue size can lead to out of memory exception. - * - * @param queueSize of queue - * @return this builder - */ - public DBMaker asyncWriteQueueSize(int queueSize){ - props.setProperty(Keys.asyncWriteQueueSize,""+queueSize); - return this; - } - - - /** - * Try to delete files after DB is closed. - * File deletion may silently fail, especially on Windows where buffer needs to be unmapped file delete. - * - * @return this builder - */ - public DBMaker deleteFilesAfterClose(){ - props.setProperty(Keys.deleteFilesAfterClose,TRUE); - return this; - } - - /** - * Adds JVM shutdown hook and closes DB just before JVM; - * - * @return this builder - */ - public DBMaker closeOnJvmShutdown(){ - props.setProperty(Keys.closeOnJvmShutdown,TRUE); - return this; - } - - /** - * Enables record compression. - *

- * Make sure you enable this every time you reopen store, otherwise record de-serialization fails unpredictably. - * - * @return this builder - */ - public DBMaker compressionEnable(){ - props.setProperty(Keys.compression,Keys.compression_lzf); - return this; - } - - - /** - * Encrypt storage using XTEA algorithm. - *

- * XTEA is sound encryption algorithm. However implementation in MapDB was not peer-reviewed. - * MapDB only encrypts records data, so attacker may see number of records and their sizes. - *

- * Make sure you enable this every time you reopen store, otherwise record de-serialization fails unpredictably. - * - * @param password for encryption - * @return this builder - */ - public DBMaker encryptionEnable(String password){ - return encryptionEnable(password.getBytes(Charset.forName("UTF8"))); - } - - - - /** - * Encrypt storage using XTEA algorithm. - *

- * XTEA is sound encryption algorithm. However implementation in MapDB was not peer-reviewed. - * MapDB only encrypts records data, so attacker may see number of records and their sizes. - *

- * Make sure you enable this every time you reopen store, otherwise record de-serialization fails unpredictably. - * - * @param password for encryption - * @return this builder - */ - public DBMaker encryptionEnable(byte[] password){ - props.setProperty(Keys.encryption, Keys.encryption_xtea); - props.setProperty(Keys.encryptionKey, toHexa(password)); - return this; - } - - - /** - * Adds CRC32 checksum at end of each record to check data integrity. - * It throws 'IOException("Checksum does not match, data broken")' on de-serialization if data are corrupted - *

- * Make sure you enable this every time you reopen store, otherwise record de-serialization fails. - * - * @return this builder - */ - public DBMaker checksumEnable(){ - props.setProperty(Keys.checksum,TRUE); - return this; - } - - - /** - * DB Get methods such as {@link DB#getTreeMap(String)} or {@link DB#getAtomicLong(String)} auto create - * new record with default values, if record with given name does not exist. This could be problem if you would like to enforce - * stricter database schema. So this parameter disables record auto creation. - * - * If this set, `DB.getXX()` will throw an exception if given name does not exist, instead of creating new record (or collection) - * - * @return this builder - */ - public DBMaker strictDBGet(){ - props.setProperty(Keys.strictDBGet,TRUE); - return this; - } - - - - - /** - * Open store in read-only mode. Any modification attempt will throw - * UnsupportedOperationException("Read-only") - * - * @return this builder - */ - public DBMaker readOnly(){ - props.setProperty(Keys.readOnly,TRUE); - return this; - } - - - - /** - * Set free space reclaim Q. It is value from 0 to 10, indicating how eagerly MapDB - * searchs for free space inside store to reuse, before expanding store file. - * 0 means that no free space will be reused and store file will just grow (effectively append only). - * 10 means that MapDB tries really hard to reuse free space, even if it may hurt performance. - * Default value is 5; - * - * - * @return this builder - */ - public DBMaker freeSpaceReclaimQ(int q){ - if(q<0||q>10) throw new IllegalArgumentException("wrong Q"); - props.setProperty(Keys.freeSpaceReclaimQ,""+q); - return this; - } - - - /** - * Disables file sync on commit. This way transactions are preserved (rollback works), - * but commits are not 'durable' and data may be lost if store is not properly closed. - * File store will get properly synced when closed. - * Disabling this will make commits faster. - * - * @return this builder - */ - public DBMaker commitFileSyncDisable(){ - props.setProperty(Keys.commitFileSyncDisable,TRUE); - return this; - } - - - /** - * Sets store size limit. Disk or memory space consumed be storage should not grow over this space. - * Limit is not strict and does not apply to some parts such as index table. Actual store size might - * be 10% or more bigger. - * - * - * @param maxSize maximal store size in GB - * @return this builder - */ - public DBMaker sizeLimit(double maxSize){ - long size = (long) (maxSize * 1024D*1024D*1024D); - props.setProperty(Keys.sizeLimit,""+size); - return this; - } - - - - - /** constructs DB using current settings */ - public DB make(){ - boolean strictGet = propsGetBool(Keys.strictDBGet); - Engine engine = makeEngine(); - boolean dbCreated = false; - try{ - DB db = new DB(engine, strictGet,false); - dbCreated = true; - return db; - }finally { - //did db creation fail? in that case close engine to unlock files - if(!dbCreated) - engine.close(); - } - } - - - public TxMaker makeTxMaker(){ - props.setProperty(Keys.fullTx,TRUE); - snapshotEnable(); - Engine e = makeEngine(); - //init catalog if needed - DB db = new DB(e); - db.commit(); - return new TxMaker(e, propsGetBool(Keys.strictDBGet), propsGetBool(Keys.snapshots)); - } - - /** constructs Engine using current settings */ - public Engine makeEngine(){ - - final boolean readOnly = propsGetBool(Keys.readOnly); - final String file = props.containsKey(Keys.file)? props.getProperty(Keys.file):""; - final String volume = props.getProperty(Keys.volume); - final String store = props.getProperty(Keys.store); - - if(readOnly && file.isEmpty()) - throw new UnsupportedOperationException("Can not open in-memory DB in read-only mode."); - - if(readOnly && !new File(file).exists() && !Keys.store_append.equals(store)){ - throw new UnsupportedOperationException("Can not open non-existing file in read-only mode."); - } - - if(propsGetLong(Keys.sizeLimit,0)>0 && Keys.store_append.equals(store)) - throw new UnsupportedOperationException("Append-Only store does not support Size Limit"); - - extendArgumentCheck(); - - Engine engine; - - if(Keys.store_heap.equals(store)){ - engine = extendHeapStore(); - - }else if(Keys.store_append.equals(store)){ - if(Keys.volume_byteBuffer.equals(volume)||Keys.volume_directByteBuffer.equals(volume)) - throw new UnsupportedOperationException("Append Storage format is not supported with in-memory dbs"); - - Fun.Function1 volFac = extendStoreVolumeFactory(false); - engine = extendStoreAppend(file, volFac); - - }else{ - Fun.Function1 volFac = extendStoreVolumeFactory(false); - Fun.Function1 indexVolFac = extendStoreVolumeFactory(true); - engine = propsGetBool(Keys.transactionDisable) ? - extendStoreDirect(file, volFac,indexVolFac): - extendStoreWAL(file, volFac, indexVolFac); - } - - engine = extendWrapStore(engine); - - if(propsGetBool(Keys.asyncWrite) && !readOnly){ - engine = extendAsyncWriteEngine(engine); - } - - final String cache = props.getProperty(Keys.cache, CC.DEFAULT_CACHE); - - if(Keys.cache_disable.equals(cache)){ - //do not wrap engine in cache - }else if(Keys.cache_hashTable.equals(cache)){ - engine = extendCacheHashTable(engine); - }else if (Keys.cache_hardRef.equals(cache)){ - engine = extendCacheHardRef(engine); - }else if (Keys.cache_weakRef.equals(cache)){ - engine = extendCacheWeakRef(engine); - }else if (Keys.cache_softRef.equals(cache)){ - engine = extendCacheSoftRef(engine); - }else if (Keys.cache_lru.equals(cache)){ - engine = extendCacheLRU(engine); - }else{ - throw new IllegalArgumentException("unknown cache type: "+cache); - } - - engine = extendWrapCache(engine); - - - if(propsGetBool(Keys.snapshots)) - engine = extendSnapshotEngine(engine); - - engine = extendWrapSnapshotEngine(engine); - - if(readOnly) - engine = new ReadOnlyEngine(engine); - - - if(propsGetBool(Keys.closeOnJvmShutdown)){ - engine = new EngineWrapper.CloseOnJVMShutdown(engine); - } - - - //try to read one record from DB, to make sure encryption and compression are correctly set. - Fun.Pair check = null; - try{ - check = (Fun.Pair) engine.get(Engine.CHECK_RECORD, Serializer.BASIC); - if(check!=null){ - if(check.a != Arrays.hashCode(check.b)) - throw new RuntimeException("invalid checksum"); - } - }catch(Throwable e){ - throw new IllegalArgumentException("Error while opening store. Make sure you have right password, compression or encryption is well configured.",e); - } - if(check == null && !engine.isReadOnly()){ - //new db, so insert testing record - byte[] b = new byte[127]; - new Random().nextBytes(b); - check = new Fun.Pair(Arrays.hashCode(b), b); - engine.update(Engine.CHECK_RECORD, check, Serializer.BASIC); - engine.commit(); - } - - - return engine; - } - - - - protected int propsGetInt(String key, int defValue){ - String ret = props.getProperty(key); - if(ret==null) return defValue; - return Integer.valueOf(ret); - } - - protected long propsGetLong(String key, long defValue){ - String ret = props.getProperty(key); - if(ret==null) return defValue; - return Long.valueOf(ret); - } - - - protected boolean propsGetBool(String key){ - String ret = props.getProperty(key); - return ret!=null && ret.equals(TRUE); - } - - protected byte[] propsGetXteaEncKey(){ - if(!Keys.encryption_xtea.equals(props.getProperty(Keys.encryption))) - return null; - return fromHexa(props.getProperty(Keys.encryptionKey)); - } - - /** - * Check if large files can be mapped into memory. - * For example 32bit JVM can only address 2GB and large files can not be mapped, - * so for 32bit JVM this function returns false. - * - */ - protected static boolean JVMSupportsLargeMappedFiles() { - String prop = System.getProperty("os.arch"); - if(prop!=null && prop.contains("64")) return true; - //TODO better check for 32bit JVM - return false; - } - - - protected int propsGetRafMode(){ - String volume = props.getProperty(Keys.volume); - if(volume==null||Keys.volume_raf.equals(volume)){ - return 2; - }else if(Keys.volume_mmapfIfSupported.equals(volume)){ - return JVMSupportsLargeMappedFiles()?0:2; - }else if(Keys.volume_mmapfPartial.equals(volume)){ - return 1; - }else if(Keys.volume_mmapf.equals(volume)){ - return 0; - } - return 2; //default option is RAF - } - - - protected Engine extendSnapshotEngine(Engine engine) { - return new TxEngine(engine,propsGetBool(Keys.fullTx)); - } - - protected Engine extendCacheLRU(Engine engine) { - int cacheSize = propsGetInt(Keys.cacheSize, CC.DEFAULT_CACHE_SIZE); - return new Caches.LRU(engine, cacheSize, cacheCondition); - } - - protected Engine extendCacheWeakRef(Engine engine) { - return new Caches.WeakSoftRef(engine,true, cacheCondition, threadFactory); - } - - protected Engine extendCacheSoftRef(Engine engine) { - return new Caches.WeakSoftRef(engine,false,cacheCondition, threadFactory); - } - - - - protected Engine extendCacheHardRef(Engine engine) { - int cacheSize = propsGetInt(Keys.cacheSize, CC.DEFAULT_CACHE_SIZE); - return new Caches.HardRef(engine,cacheSize, cacheCondition); - } - - protected Engine extendCacheHashTable(Engine engine) { - int cacheSize = propsGetInt(Keys.cacheSize, CC.DEFAULT_CACHE_SIZE); - return new Caches.HashTable(engine, cacheSize, cacheCondition); - } - - protected Engine extendAsyncWriteEngine(Engine engine) { - return new AsyncWriteEngine(engine, - propsGetInt(Keys.asyncWriteFlushDelay,CC.ASYNC_WRITE_FLUSH_DELAY), - propsGetInt(Keys.asyncWriteQueueSize,CC.ASYNC_WRITE_QUEUE_SIZE), - null); - } - - - protected void extendArgumentCheck() { - } - - protected Engine extendWrapStore(Engine engine) { - return engine; - } - - - protected Engine extendWrapCache(Engine engine) { - return engine; - } - - protected Engine extendWrapSnapshotEngine(Engine engine) { - return engine; - } - - - protected Engine extendHeapStore() { - return new StoreHeap(); - } - - protected Engine extendStoreAppend(String fileName, Fun.Function1 volumeFactory) { - boolean compressionEnabled = Keys.compression_lzf.equals(props.getProperty(Keys.compression)); - return new StoreAppend(fileName, volumeFactory, - propsGetRafMode()>0, propsGetBool(Keys.readOnly), - propsGetBool(Keys.transactionDisable), - propsGetBool(Keys.deleteFilesAfterClose), - propsGetBool(Keys.commitFileSyncDisable), - propsGetBool(Keys.checksum),compressionEnabled,propsGetXteaEncKey()); - } - - protected Engine extendStoreDirect( - String fileName, - Fun.Function1 volumeFactory, - Fun.Function1 indexVolumeFactory) { - boolean compressionEnabled = Keys.compression_lzf.equals(props.getProperty(Keys.compression)); - return new StoreDirect( - fileName, - volumeFactory, - indexVolumeFactory, - propsGetBool(Keys.readOnly), - propsGetBool(Keys.deleteFilesAfterClose), - propsGetInt(Keys.freeSpaceReclaimQ,CC.DEFAULT_FREE_SPACE_RECLAIM_Q), - propsGetBool(Keys.commitFileSyncDisable), - propsGetLong(Keys.sizeLimit,0), - propsGetBool(Keys.checksum),compressionEnabled,propsGetXteaEncKey(), - 0); - } - - protected Engine extendStoreWAL( - String fileName, - Fun.Function1 volumeFactory, - Fun.Function1 indexVolumeFactory) { - boolean compressionEnabled = Keys.compression_lzf.equals(props.getProperty(Keys.compression)); - return new StoreWAL( - fileName, - volumeFactory, - indexVolumeFactory, - propsGetBool(Keys.readOnly), - propsGetBool(Keys.deleteFilesAfterClose), - propsGetInt(Keys.freeSpaceReclaimQ,CC.DEFAULT_FREE_SPACE_RECLAIM_Q), - propsGetBool(Keys.commitFileSyncDisable), - propsGetLong(Keys.sizeLimit,-1), - propsGetBool(Keys.checksum),compressionEnabled,propsGetXteaEncKey(), - 0); - } - - - protected Fun.Function1 extendStoreVolumeFactory(boolean index) { - long sizeLimit = propsGetLong(Keys.sizeLimit,0); - String volume = props.getProperty(Keys.volume); - if(Keys.volume_byteBuffer.equals(volume)) - return Volume.memoryFactory(false,sizeLimit,CC.VOLUME_SLICE_SHIFT); - else if(Keys.volume_directByteBuffer.equals(volume)) - return Volume.memoryFactory(true,sizeLimit,CC.VOLUME_SLICE_SHIFT); - - boolean raf = propsGetRafMode()!=0; - if(raf && index && propsGetRafMode()==1) - raf = false; - - return Volume.fileFactory(raf, propsGetBool(Keys.readOnly), - sizeLimit,CC.VOLUME_SLICE_SHIFT,0); - } - - protected static String toHexa( byte [] bb ) { - char[] HEXA_CHARS = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - char[] ret = new char[bb.length*2]; - for(int i=0;i> 4)]; - ret[i*2+1] = HEXA_CHARS[((bb[i] & 0x0F))]; - } - return new String(ret); - } - - protected static byte[] fromHexa(String s ) { - byte[] ret = new byte[s.length()/2]; - for(int i=0;i>>= 7; - //$DELAY$ - } - //$DELAY$ - out.write((byte) value); - } - - /** - * Pack int into output stream. - * It will occupy 1-5 bytes depending on value (lower values occupy smaller space) - * - * This method originally comes from Kryo Framework, author Nathan Sweet. - * It was modified to fit MapDB needs. - * - * @param in DataOutput to put value into - * @param value to be serialized, must be non-negative - * @throws java.io.IOException - */ - - static public void packInt(DataOutput in, int value) throws IOException { - //$DELAY$ - while ((value & ~0x7F) != 0) { - //$DELAY$ - in.write(((value & 0x7F) | 0x80)); - value >>>= 7; - } - //$DELAY$ - in.write((byte) value); - } - - public static int longHash(final long key) { - //$DELAY$ - int h = (int)(key ^ (key >>> 32)); - h ^= (h >>> 20) ^ (h >>> 12); - return h ^ (h >>> 7) ^ (h >>> 4); - } - - public static int intHash(int h) { - //$DELAY$ - h ^= (h >>> 20) ^ (h >>> 12); - return h ^ (h >>> 7) ^ (h >>> 4); - } - - - /** - * Give access to internal byte[] or ByteBuffer in DataInput2.. - * Should not be used unless you are writing MapDB extension and needs some performance bonus - */ - interface DataInputInternal extends DataInput,Closeable { - - int getPos(); - void setPos(int pos); - - /** return underlying `byte[]` or null if it does not exist*/ - byte[] internalByteArray(); - - /** return underlying `ByteBuffer` or null if it does not exist*/ - ByteBuffer internalByteBuffer(); - - - void close(); - } - - /** DataInput on top of `byte[]` */ - static public final class DataInputByteArray implements DataInput, DataInputInternal { - protected final byte[] buf; - protected int pos; - - - public DataInputByteArray(byte[] b) { - this(b, 0); - } - - public DataInputByteArray(byte[] bb, int pos) { - //$DELAY$ - buf = bb; - this.pos = pos; - } - - @Override - public void readFully(byte[] b) throws IOException { - readFully(b, 0, b.length); - } - - @Override - public void readFully(byte[] b, int off, int len) throws IOException { - System.arraycopy(buf, pos, b, off, len); - //$DELAY$ - pos += len; - } - - @Override - public int skipBytes(final int n) throws IOException { - pos += n; - //$DELAY$ - return n; - } - - @Override - public boolean readBoolean() throws IOException { - //$DELAY$ - return buf[pos++] == 1; - } - - @Override - public byte readByte() throws IOException { - //$DELAY$ - return buf[pos++]; - } - - @Override - public int readUnsignedByte() throws IOException { - //$DELAY$ - return buf[pos++] & 0xff; - } - - @Override - public short readShort() throws IOException { - //$DELAY$ - return (short)((buf[pos++] << 8) | (buf[pos++] & 0xff)); - } - - @Override - public int readUnsignedShort() throws IOException { - //$DELAY$ - return (((buf[pos++] & 0xff) << 8) | - ((buf[pos++] & 0xff))); - } - - @Override - public char readChar() throws IOException { - //$DELAY$ - // I know: 4 bytes, but char only consumes 2, - // has to stay here for backward compatibility - //TODO char 4 byte - return (char) readInt(); - } - - @Override - public int readInt() throws IOException { - final int end = pos + 4; - int ret = 0; - for (; pos < end; pos++) { - //$DELAY$ - ret = (ret << 8) | (buf[pos] & 0xFF); - } - return ret; - } - - @Override - public long readLong() throws IOException { - final int end = pos + 8; - long ret = 0; - for (; pos < end; pos++) { - //$DELAY$ - ret = (ret << 8) | (buf[pos] & 0xFF); - } - return ret; - } - - @Override - public float readFloat() throws IOException { - return Float.intBitsToFloat(readInt()); - } - - @Override - public double readDouble() throws IOException { - return Double.longBitsToDouble(readLong()); - } - - @Override - public String readLine() throws IOException { - return readUTF(); - } - - @Override - public String readUTF() throws IOException { - final int len = unpackInt(); - char[] b = new char[len]; - for (int i = 0; i < len; i++) - //$DELAY$ - //TODO char 4 bytes - b[i] = (char) unpackInt(); - return new String(b); - } - - @Override - public int getPos() { - return pos; - } - - @Override - public void setPos(int pos) { - this.pos = pos; - } - - @Override - public byte[] internalByteArray() { - return buf; - } - - @Override - public ByteBuffer internalByteBuffer() { - return null; - } - - @Override - public void close() { - } - - protected int unpackInt() throws IOException { - int offset = 0; - int result=0; - int b; - do { - //$DELAY$ - b = buf[pos++]; - result |= (b & 0x7F) << offset; - offset += 7; - }while((b & 0x80) != 0); - //$DELAY$ - return result; - } - - - } - - - /** - * Wraps `DataInput` into `InputStream` - */ - public static final class DataInputToStream extends InputStream { - - protected final DataInput in; - - public DataInputToStream(DataInput in) { - this.in = in; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - in.readFully(b,off,len); - return len; - } - - @Override - public long skip(long n) throws IOException { - n = Math.min(n, Integer.MAX_VALUE); - //$DELAY$ - return in.skipBytes((int) n); - } - - @Override - public void close() throws IOException { - if(in instanceof Closeable) - ((Closeable) in).close(); - } - - @Override - public int read() throws IOException { - return in.readUnsignedByte(); - } - } - - - /** - * Wraps {@link java.nio.ByteBuffer} and provides {@link java.io.DataInput} - * - * @author Jan Kotek - */ - public static final class DataInputByteBuffer implements DataInput, DataInputInternal { - - public final ByteBuffer buf; - public int pos; - - public DataInputByteBuffer(final ByteBuffer buf, final int pos) { - //$DELAY$ - this.buf = buf; - this.pos = pos; - } - - /** - * @deprecated use {@link org.mapdb.DataIO.DataInputByteArray} - */ - public DataInputByteBuffer(byte[] b) { - this(ByteBuffer.wrap(b),0); - } - - @Override - public void readFully(byte[] b) throws IOException { - readFully(b, 0, b.length); - } - - @Override - public void readFully(byte[] b, int off, int len) throws IOException { - ByteBuffer clone = buf.duplicate(); - clone.position(pos); - //$DELAY$ - pos+=len; - clone.get(b, off, len); - } - - @Override - public int skipBytes(final int n) throws IOException { - pos +=n; - //$DELAY$ - return n; - } - - @Override - public boolean readBoolean() throws IOException { - //$DELAY$ - return buf.get(pos++) ==1; - } - - @Override - public byte readByte() throws IOException { - //$DELAY$ - return buf.get(pos++); - } - - @Override - public int readUnsignedByte() throws IOException { - //$DELAY$ - return buf.get(pos++)& 0xff; - } - - @Override - public short readShort() throws IOException { - final short ret = buf.getShort(pos); - //$DELAY$ - pos+=2; - return ret; - } - - @Override - public int readUnsignedShort() throws IOException { - //$DELAY$ - return (( (buf.get(pos++) & 0xff) << 8) | - ( (buf.get(pos++) & 0xff))); - } - - @Override - public char readChar() throws IOException { - //$DELAY$ - // I know: 4 bytes, but char only consumes 2, - // has to stay here for backward compatibility - //TODO 4 byte char - return (char) readInt(); - } - - @Override - public int readInt() throws IOException { - final int ret = buf.getInt(pos); - //$DELAY$ - pos+=4; - return ret; - } - - @Override - public long readLong() throws IOException { - final long ret = buf.getLong(pos); - //$DELAY$ - pos+=8; - return ret; - } - - @Override - public float readFloat() throws IOException { - final float ret = buf.getFloat(pos); - //$DELAY$ - pos+=4; - return ret; - } - - @Override - public double readDouble() throws IOException { - final double ret = buf.getDouble(pos); - //$DELAY$ - pos+=8; - return ret; - } - - @Override - public String readLine() throws IOException { - return readUTF(); - } - - @Override - public String readUTF() throws IOException { - final int size = unpackInt(this); - //$DELAY$ - return SerializerBase.deserializeString(this, size); - } - - - - - - - @Override - public int getPos() { - return pos; - } - - @Override - public void setPos(int pos) { - this.pos = pos; - } - - @Override - public byte[] internalByteArray() { - return null; - } - - @Override - public ByteBuffer internalByteBuffer() { - return buf; - } - - @Override - public void close() { - } - } - - /** - * Provides {@link java.io.DataOutput} implementation on top of growable {@code byte[]} - *

- * {@link java.io.ByteArrayOutputStream} is not used as it requires {@code byte[]} copying - * - * @author Jan Kotek - */ - public static final class DataOutputByteArray extends OutputStream implements DataOutput { - - public byte[] buf; - public int pos; - public int sizeMask; - - - public DataOutputByteArray(){ - pos = 0; - buf = new byte[16]; //TODO take hint from serializer for initial size - sizeMask = 0xFFFFFFFF-(buf.length-1); - } - - - public byte[] copyBytes(){ - return Arrays.copyOf(buf, pos); - } - - /** - * make sure there will be enough space in buffer to write N bytes - */ - public void ensureAvail(int n) { - //$DELAY$ - n+=pos; - if ((n&sizeMask)!=0) { - //$DELAY$ - int newSize = buf.length; - while(newSize> 8)); - //$DELAY$ - buf[pos++] = (byte) (0xff & (v)); - } - - @Override - public void writeChar(final int v) throws IOException { - // I know: 4 bytes, but char only consumes 2, - // has to stay here for backward compatibility - //TODO 4 byte char - writeInt(v); - } - - @Override - public void writeInt(final int v) throws IOException { - ensureAvail(4); - buf[pos++] = (byte) (0xff & (v >> 24)); - //$DELAY$ - buf[pos++] = (byte) (0xff & (v >> 16)); - buf[pos++] = (byte) (0xff & (v >> 8)); - //$DELAY$ - buf[pos++] = (byte) (0xff & (v)); - } - - @Override - public void writeLong(final long v) throws IOException { - ensureAvail(8); - buf[pos++] = (byte) (0xff & (v >> 56)); - buf[pos++] = (byte) (0xff & (v >> 48)); - //$DELAY$ - buf[pos++] = (byte) (0xff & (v >> 40)); - buf[pos++] = (byte) (0xff & (v >> 32)); - buf[pos++] = (byte) (0xff & (v >> 24)); - //$DELAY$ - buf[pos++] = (byte) (0xff & (v >> 16)); - buf[pos++] = (byte) (0xff & (v >> 8)); - buf[pos++] = (byte) (0xff & (v)); - //$DELAY$ - } - - @Override - public void writeFloat(final float v) throws IOException { - writeInt(Float.floatToIntBits(v)); - } - - @Override - public void writeDouble(final double v) throws IOException { - writeLong(Double.doubleToLongBits(v)); - } - - @Override - public void writeBytes(final String s) throws IOException { - writeUTF(s); - } - - @Override - public void writeChars(final String s) throws IOException { - writeUTF(s); - } - - @Override - public void writeUTF(final String s) throws IOException { - final int len = s.length(); - packInt(len); - for (int i = 0; i < len; i++) { - //$DELAY$ - int c = (int) s.charAt(i); - packInt(c); - } - } - - //TODO remove pack methods perhaps - protected void packInt(int value) throws IOException { - if(CC.PARANOID && value<0) - throw new AssertionError("negative value: "+value); - - while ((value & ~0x7F) != 0) { - ensureAvail(1); - //$DELAY$ - buf[pos++]= (byte) ((value & 0x7F) | 0x80); - value >>>= 7; - } - //$DELAY$ - ensureAvail(1); - buf[pos++]= (byte) value; - } - - } - -} diff --git a/src/main/java/org/mapdb/EncryptionXTEA.java b/src/main/java/org/mapdb/EncryptionXTEA.java deleted file mode 100644 index 68ea64955..000000000 --- a/src/main/java/org/mapdb/EncryptionXTEA.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * This code comes from H2 database project and was modified for MapDB a bit. - * Re-licensed under Apache 2 license with Thomas Mueller permission - * - * Copyright (c) 2004-2011 H2 Group - * - * 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 - * - * http://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. - */ - -package org.mapdb; - - -import java.util.Arrays; - -/** - * An implementation of the EncryptionXTEA block cipher algorithm. - *

- * This implementation uses 32 rounds. - * The best attack reported as of 2009 is 36 rounds (Wikipedia). - *

- * It requires 32 byte long encryption key, so SHA256 password hash is used. - */ -public final class EncryptionXTEA{ - - /** - * Blocks sizes are always multiples of this number. - */ - public static final int ALIGN = 16; - - private static final int DELTA = 0x9E3779B9; - private final int k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15; - private final int k16, k17, k18, k19, k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k30, k31; - - - public EncryptionXTEA(byte[] password) { - byte[] b = getHash(password); - int[] key = new int[4]; - for (int i = 0; i < 16;) { - key[i / 4] = (b[i++] << 24) + ((b[i++] & 255) << 16) + ((b[i++] & 255) << 8) + (b[i++] & 255); - } - int[] r = new int[32]; - for (int i = 0, sum = 0; i < 32;) { - r[i++] = sum + key[sum & 3]; - sum += DELTA; - r[i++] = sum + key[ (sum >>> 11) & 3]; - } - k0 = r[0]; k1 = r[1]; k2 = r[2]; k3 = r[3]; k4 = r[4]; k5 = r[5]; k6 = r[6]; k7 = r[7]; - k8 = r[8]; k9 = r[9]; k10 = r[10]; k11 = r[11]; k12 = r[12]; k13 = r[13]; k14 = r[14]; k15 = r[15]; - k16 = r[16]; k17 = r[17]; k18 = r[18]; k19 = r[19]; k20 = r[20]; k21 = r[21]; k22 = r[22]; k23 = r[23]; - k24 = r[24]; k25 = r[25]; k26 = r[26]; k27 = r[27]; k28 = r[28]; k29 = r[29]; k30 = r[30]; k31 = r[31]; - } - - - public void encrypt(byte[] bytes, int off, int len) { - if(CC.PARANOID && ! (len % ALIGN == 0)) - throw new AssertionError("unaligned len " + len); - - for (int i = off; i < off + len; i += 8) { - encryptBlock(bytes, bytes, i); - } - } - - public void decrypt(byte[] bytes, int off, int len) { - if(CC.PARANOID && ! (len % ALIGN == 0)) - throw new AssertionError("unaligned len " + len); - - for (int i = off; i < off + len; i += 8) { - decryptBlock(bytes, bytes, i); - } - } - - private void encryptBlock(byte[] in, byte[] out, int off) { - int y = (in[off] << 24) | ((in[off+1] & 255) << 16) | ((in[off+2] & 255) << 8) | (in[off+3] & 255); - int z = (in[off+4] << 24) | ((in[off+5] & 255) << 16) | ((in[off+6] & 255) << 8) | (in[off+7] & 255); - y += (((z << 4) ^ (z >>> 5)) + z) ^ k0; z += (((y >>> 5) ^ (y << 4)) + y) ^ k1; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k2; z += (((y >>> 5) ^ (y << 4)) + y) ^ k3; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k4; z += (((y >>> 5) ^ (y << 4)) + y) ^ k5; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k6; z += (((y >>> 5) ^ (y << 4)) + y) ^ k7; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k8; z += (((y >>> 5) ^ (y << 4)) + y) ^ k9; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k10; z += (((y >>> 5) ^ (y << 4)) + y) ^ k11; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k12; z += (((y >>> 5) ^ (y << 4)) + y) ^ k13; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k14; z += (((y >>> 5) ^ (y << 4)) + y) ^ k15; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k16; z += (((y >>> 5) ^ (y << 4)) + y) ^ k17; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k18; z += (((y >>> 5) ^ (y << 4)) + y) ^ k19; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k20; z += (((y >>> 5) ^ (y << 4)) + y) ^ k21; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k22; z += (((y >>> 5) ^ (y << 4)) + y) ^ k23; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k24; z += (((y >>> 5) ^ (y << 4)) + y) ^ k25; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k26; z += (((y >>> 5) ^ (y << 4)) + y) ^ k27; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k28; z += (((y >>> 5) ^ (y << 4)) + y) ^ k29; - y += (((z << 4) ^ (z >>> 5)) + z) ^ k30; z += (((y >>> 5) ^ (y << 4)) + y) ^ k31; - out[off] = (byte) (y >> 24); out[off+1] = (byte) (y >> 16); out[off+2] = (byte) (y >> 8); out[off+3] = (byte) y; - out[off+4] = (byte) (z >> 24); out[off+5] = (byte) (z >> 16); out[off+6] = (byte) (z >> 8); out[off+7] = (byte) z; - } - - private void decryptBlock(byte[] in, byte[] out, int off) { - int y = (in[off] << 24) | ((in[off+1] & 255) << 16) | ((in[off+2] & 255) << 8) | (in[off+3] & 255); - int z = (in[off+4] << 24) | ((in[off+5] & 255) << 16) | ((in[off+6] & 255) << 8) | (in[off+7] & 255); - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k31; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k30; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k29; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k28; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k27; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k26; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k25; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k24; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k23; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k22; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k21; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k20; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k19; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k18; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k17; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k16; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k15; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k14; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k13; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k12; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k11; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k10; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k9; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k8; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k7; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k6; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k5; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k4; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k3; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k2; - z -= (((y >>> 5) ^ (y << 4)) + y) ^ k1; y -= (((z << 4) ^ (z >>> 5)) + z) ^ k0; - out[off] = (byte) (y >> 24); out[off+1] = (byte) (y >> 16); out[off+2] = (byte) (y >> 8); out[off+3] = (byte) y; - out[off+4] = (byte) (z >> 24); out[off+5] = (byte) (z >> 16); out[off+6] = (byte) (z >> 8); out[off+7] = (byte) z; - } - - - - - /** - * Calculate the SHA256 hash code for the given data. Used to hash password. - * - * - * @param data the data to hash - * @return the hash code - */ - public static byte[] getHash(byte[] data) { - /** - * The first 32 bits of the fractional parts of the cube roots of the first - * sixty-four prime numbers. Used for SHA256 password hash - */ - final int[] K = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, - 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, - 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, - 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, - 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, - 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, - 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, - 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, - 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, - 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; - - int byteLen = data.length; - int intLen = ((byteLen + 9 + 63) / 64) * 16; - byte[] bytes = new byte[intLen * 4]; - System.arraycopy(data, 0, bytes, 0, byteLen); - - bytes[byteLen] = (byte) 0x80; - int[] buff = new int[intLen]; - for (int i = 0, j = 0; j < intLen; i += 4, j++) { - buff[j] = readInt(bytes, i); - } - buff[intLen - 2] = byteLen >>> 29; - buff[intLen - 1] = byteLen << 3; - int[] w = new int[64]; - int[] hh = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; - for (int block = 0; block < intLen; block += 16) { - System.arraycopy(buff, block + 0, w, 0, 16); - for (int i = 16; i < 64; i++) { - int x = w[i - 2]; - int theta1 = rot(x, 17) ^ rot(x, 19) ^ (x >>> 10); - x = w[i - 15]; - int theta0 = rot(x, 7) ^ rot(x, 18) ^ (x >>> 3); - w[i] = theta1 + w[i - 7] + theta0 + w[i - 16]; - } - - int a = hh[0], b = hh[1], c = hh[2], d = hh[3]; - int e = hh[4], f = hh[5], g = hh[6], h = hh[7]; - - for (int i = 0; i < 64; i++) { - int t1 = h + (rot(e, 6) ^ rot(e, 11) ^ rot(e, 25)) - + ((e & f) ^ ((~e) & g)) + K[i] + w[i]; - int t2 = (rot(a, 2) ^ rot(a, 13) ^ rot(a, 22)) - + ((a & b) ^ (a & c) ^ (b & c)); - h = g; - g = f; - f = e; - e = d + t1; - d = c; - c = b; - b = a; - a = t1 + t2; - } - hh[0] += a; - hh[1] += b; - hh[2] += c; - hh[3] += d; - hh[4] += e; - hh[5] += f; - hh[6] += g; - hh[7] += h; - } - byte[] result = new byte[32]; - for (int i = 0; i < 8; i++) { - writeInt(result, i * 4, hh[i]); - } - Arrays.fill(w, 0); - Arrays.fill(buff, 0); - Arrays.fill(hh, 0); - Arrays.fill(bytes, (byte) 0); - return result; - } - - private static int rot(int i, int count) { - return (i << (32 - count)) | (i >>> count); - } - - private static int readInt(byte[] b, int i) { - return ((b[i] & 0xff) << 24) + ((b[i + 1] & 0xff) << 16) - + ((b[i + 2] & 0xff) << 8) + (b[i + 3] & 0xff); - } - - private static void writeInt(byte[] b, int i, int value) { - b[i] = (byte) (value >> 24); - b[i + 1] = (byte) (value >> 16); - b[i + 2] = (byte) (value >> 8); - b[i + 3] = (byte) value; - } - - -} diff --git a/src/main/java/org/mapdb/Engine.java b/src/main/java/org/mapdb/Engine.java deleted file mode 100644 index 042899e6e..000000000 --- a/src/main/java/org/mapdb/Engine.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.io.Closeable; - -/** - * Centerpiece for record management, `Engine` is simple key value store. - * Engine is low-level interface and is not meant to be used directly - * by user. For most operations user should use {@link DB} class. - * - * In this store key is primitive `long` number, typically pointer to index table. - * Value is class instance. To turn value into/from binary form serializer is - * required as extra argument for most operations. - * - * Unlike other DBs MapDB does not expect user to (de)serialize data before - * they are passed as arguments. Instead MapDB controls (de)serialization itself. - * This gives DB a lot of flexibility: for example instances may be held in - * cache to minimise number of deserializations, or modified instance can - * be placed into queue and asynchronously written on background thread. - * - * There is {@link Store} subinterface for raw persistence - * Most of MapDB features comes from {@link EngineWrapper}s, which are stacked on - * top of each other to provide asynchronous writes, instance cache, encryption etc.. - * `Engine` stack is very elegant and uniform way to handle additional functionality. - * Other DBs need an ORM framework to achieve similar features. - - * In default configuration MapDB runs with this `Engine` stack: - * - * * **DISK** - raw file or memory - * * {@link org.mapdb.StoreWAL} - permanent record store with transactions - * * {@link org.mapdb.Caches.HashTable} - instance cache - * * **USER** - {@link DB} and collections - * - * TODO document more examples of Engine wrappers - * - * Engine uses `recid` to identify records. There is zero error handling in case recid is invalid - * (random number or already deleted record). Passing illegal recid may result into anything - * (return null, throw EOF or even corrupt store). Engine is considered low-level component - * and it is responsibility of upper layers (collections) to ensure recid is consistent. - * Lack of error handling is trade of for speed (similar way as manual memory management in C++) - *

- * Engine must support `null` record values. You may insert, update and fetch null records. - * Nulls play important role in recid preallocation and asynchronous writes. - *

- * Recid can be reused after it was deleted. If your application relies on unique being unique, - * you should update record with null value, instead of delete. - * Null record consumes only 8 bytes in store and is preserved during defragmentation. - * - * @author Jan Kotek - */ -public interface Engine extends Closeable { - - long CATALOG_RECID = 1; - long CLASS_INFO_RECID = 2; - long CHECK_RECORD = 3; - long LAST_RESERVED_RECID = 7; - - - /** - * Preallocates recid for not yet created record. It does not insert any data into it. - * @return new recid - */ - long preallocate(); - - /** - * Preallocates recids for not yet created record. It does not insert any data into it. - * This is done in batch of given size (determied by size of array in argument) - * @param recids array to put result into - */ - void preallocate(long[] recids); - - /** - * Insert new record. - * - * @param value records to be added - * @param serializer used to convert record into/from binary form - * @return recid (record identifier) under which record is stored. - */ - long put(A value, Serializer serializer); - - /** - * Get existing record. - *

- * Recid must be a number returned by 'put' method. - * Behaviour for invalid recid (random number or already deleted record) - * is not defined, typically it returns null or throws 'EndOfFileException' - * - * @param recid (record identifier) under which record was persisted - * @param serializer used to deserialize record from binary form - * @return record matching given recid, or null if record is not found under given recid. - */ - A get(long recid, Serializer serializer); - - /** - * Update existing record with new value. - *

- * Recid must be a number returned by 'put' method. - * Behaviour for invalid recid (random number or already deleted record) - * is not defined, typically it throws 'EndOfFileException', - * but it may also corrupt store. - * - * @param recid (record identifier) under which record was persisted. - * @param value new record value to be stored - * @param serializer used to serialize record into binary form - */ - void update(long recid, A value, Serializer serializer); - - - /** - * Updates existing record in atomic (Compare And Swap) manner. - * Value is modified only if old value matches expected value. There are three ways to match values, MapDB may use any of them: - *

    - *
  1. Equality check oldValue==expectedOldValue when old value is found in instance cache
  2. - *
  3. Deserializing oldValue using serializer and checking oldValue.equals(expectedOldValue)
  4. - *
  5. Serializing expectedOldValue using serializer and comparing binary array with already serialized oldValue - *
- *

- * Recid must be a number returned by 'put' method. - * Behaviour for invalid recid (random number or already deleted record) - * is not defined, typically it throws 'EndOfFileException', - * but it may also corrupt store. - * - * @param recid (record identifier) under which record was persisted. - * @param expectedOldValue old value to be compared with existing record - * @param newValue to be written if values are matching - * @param serializer used to serialize record into binary form - * @return true if values matched and newValue was written - */ - boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer); - - /** - * Remove existing record from store/cache - * - *

- * Recid must be a number returned by 'put' method. - * Behaviour for invalid recid (random number or already deleted record) - * is not defined, typically it throws 'EndOfFileException', - * but it may also corrupt store. - * - * @param recid (record identifier) under which was record persisted - * @param serializer which may be used in some circumstances to deserialize and store old object - */ - void delete(long recid, Serializer serializer); - - - - /** - * Close store/cache. This method must be called before JVM exits to flush all caches and prevent store corruption. - * Also it releases resources used by MapDB (disk, memory..). - *

- * Engine can no longer be used after this method was called. If Engine is used after closing, it may - * throw any exception including NullPointerException - *

- * There is an configuration option {@link DBMaker#closeOnJvmShutdown()} which uses shutdown hook to automatically - * close Engine when JVM shutdowns. - */ - void close(); - - - /** - * Checks whether Engine was closed. - * - * @return true if engine was closed - */ - public boolean isClosed(); - - /** - * Makes all changes made since the previous commit/rollback permanent. - * In transactional mode (on by default) it means creating journal file and replaying it to storage. - * In other modes it may flush disk caches or do nothing at all (check your config options) - */ - void commit(); - - /** - * Undoes all changes made in the current transaction. - * If transactions are disabled it throws {@link UnsupportedOperationException}. - * - * @throws UnsupportedOperationException if transactions are disabled - */ - void rollback() throws UnsupportedOperationException; - - /** - * Check if you can write into this Engine. It may be readonly in some cases (snapshot, read-only files). - * - * @return true if engine is read-only - */ - boolean isReadOnly(); - - /** @return true if engine supports rollback*/ - boolean canRollback(); - - /** @return true if engine can create read-only snapshots*/ - boolean canSnapshot(); - - /** - * Returns read-only snapshot of data in Engine. - * - * @see EngineWrapper#canSnapshot() - * @throws UnsupportedOperationException if snapshots are not supported/enabled - */ - Engine snapshot() throws UnsupportedOperationException; - - - /** clears any underlying cache */ - void clearCache(); - - void compact(); - - /** - * Returns default serializer associated with this engine. - * The default serializer will be moved from Engine into DB, so it is deprecated now and - * this method will be removed. - * - */ - @Deprecated - SerializerPojo getSerializerPojo(); - -} diff --git a/src/main/java/org/mapdb/EngineWrapper.java b/src/main/java/org/mapdb/EngineWrapper.java deleted file mode 100644 index 5e2f5a6fc..000000000 --- a/src/main/java/org/mapdb/EngineWrapper.java +++ /dev/null @@ -1,580 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - - -import java.io.IOError; -import java.io.IOException; -import java.util.Arrays; -import java.util.Iterator; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Logger; - - -/** - * EngineWrapper adapter. It implements all methods on Engine interface. - * - * @author Jan Kotek - */ -public class EngineWrapper implements Engine{ - - protected static final Logger LOG = !CC.LOG_EWRAP?null : - Logger.getLogger(EngineWrapper.class.getName()); - - - - private Engine engine; - - protected EngineWrapper(Engine engine){ - if(engine == null) throw new IllegalArgumentException(); - this.engine = engine; - } - - @Override - public long preallocate(){ - return getWrappedEngine().preallocate(); - } - - @Override - public void preallocate(long[] recids){ - getWrappedEngine().preallocate(recids); - } - - @Override - public long put(A value, Serializer serializer) { - return getWrappedEngine().put(value, serializer); - } - - @Override - public A get(long recid, Serializer serializer) { - return getWrappedEngine().get(recid, serializer); - } - - @Override - public void update(long recid, A value, Serializer serializer) { - getWrappedEngine().update(recid, value, serializer); - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - return getWrappedEngine().compareAndSwap(recid, expectedOldValue, newValue, serializer); - } - - @Override - public void delete(long recid, Serializer serializer) { - getWrappedEngine().delete(recid, serializer); - } - - @Override - public void close() { - Engine e = engine; - try{ - if(e!=null) - e.close(); - } finally { - engine = CLOSED; - } - } - - @Override - public boolean isClosed() { - return engine==CLOSED || engine==null; - } - - @Override - public void commit() { - getWrappedEngine().commit(); - } - - @Override - public void rollback() { - getWrappedEngine().rollback(); - } - - - @Override - public boolean isReadOnly() { - return getWrappedEngine().isReadOnly(); - } - - @Override - public boolean canRollback() { - return getWrappedEngine().canRollback(); - } - - @Override - public boolean canSnapshot() { - return getWrappedEngine().canSnapshot(); - } - - @Override - public Engine snapshot() throws UnsupportedOperationException { - return getWrappedEngine().snapshot(); - } - - @Override - public void clearCache() { - getWrappedEngine().clearCache(); - } - - @Override - public void compact() { - getWrappedEngine().compact(); - } - - @Override - public SerializerPojo getSerializerPojo() { - return getWrappedEngine().getSerializerPojo(); - } - - - public Engine getWrappedEngine(){ - return checkClosed(engine); - } - - protected static V checkClosed(V v){ - if(v==null) throw new IllegalAccessError("DB has been closed"); - return v; - } - - - /** - * Wraps an Engine and throws - * UnsupportedOperationException("Read-only") - * on any modification attempt. - */ - public static class ReadOnlyEngine extends EngineWrapper { - - - public ReadOnlyEngine(Engine engine){ - super(engine); - } - - - @Override - public long preallocate() { - throw new UnsupportedOperationException("Read-only"); - } - - @Override - public void preallocate(long[] recids){ - throw new UnsupportedOperationException("Read-only"); - } - - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - throw new UnsupportedOperationException("Read-only"); - } - - @Override - public long put(A value, Serializer serializer) { - throw new UnsupportedOperationException("Read-only"); - } - - @Override - public void update(long recid, A value, Serializer serializer) { - throw new UnsupportedOperationException("Read-only"); - } - - @Override - public void delete(long recid, Serializer serializer){ - throw new UnsupportedOperationException("Read-only"); - } - - @Override - public void commit() { - throw new UnsupportedOperationException("Read-only"); - } - - @Override - public void rollback() { - throw new UnsupportedOperationException("Read-only"); - } - - - @Override - public boolean isReadOnly() { - return true; - } - - @Override - public boolean canSnapshot() { - return true; - } - - @Override - public Engine snapshot() throws UnsupportedOperationException { - return this; - } - - } - - - /** - * check if Record Instances were not modified while in cache. - * Usuful to diagnose strange problems with Instance Cache. - */ - public static class ImmutabilityCheckEngine extends EngineWrapper{ - - protected static class Item { - final Serializer serializer; - final Object item; - final int oldChecksum; - - public Item(Serializer serializer, Object item) { - if(item==null || serializer==null) throw new AssertionError("null"); - this.serializer = serializer; - this.item = item; - oldChecksum = checksum(); - if(oldChecksum!=checksum()) throw new AssertionError("inconsistent serialization"); - } - - private int checksum(){ - try { - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - serializer.serialize(out, item); - byte[] bb = out.copyBytes(); - return Arrays.hashCode(bb); - }catch(IOException e){ - throw new IOError(e); - } - } - - void check(){ - int newChecksum = checksum(); - if(oldChecksum!=newChecksum) throw new AssertionError("Record instance was modified: \n "+item+"\n "+serializer); - } - } - - protected LongConcurrentHashMap items = new LongConcurrentHashMap(); - - protected ImmutabilityCheckEngine(Engine engine) { - super(engine); - } - - @Override - public A get(long recid, Serializer serializer) { - Item item = items.get(recid); - if(item!=null) item.check(); - A ret = super.get(recid, serializer); - if(ret!=null) items.put(recid, new Item(serializer,ret)); - return ret; - } - - @Override - public long put(A value, Serializer serializer) { - long ret = super.put(value, serializer); - if(value!=null) items.put(ret, new Item(serializer,value)); - return ret; - } - - @Override - public void update(long recid, A value, Serializer serializer) { - Item item = items.get(recid); - if(item!=null) item.check(); - super.update(recid, value, serializer); - if(value!=null) items.put(recid, new Item(serializer,value)); - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - Item item = items.get(recid); - if(item!=null) item.check(); - boolean ret = super.compareAndSwap(recid, expectedOldValue, newValue, serializer); - if(ret && newValue!=null) items.put(recid, new Item(serializer,item)); - return ret; - } - - @Override - public void close() { - super.close(); - for(Iterator iter = items.valuesIterator(); iter.hasNext();){ - iter.next().check(); - } - items.clear(); - } - } - - - /** Engine wrapper with all methods synchronized on global lock, useful to diagnose concurrency issues.*/ - public static class SynchronizedEngineWrapper extends EngineWrapper{ - - protected SynchronizedEngineWrapper(Engine engine) { - super(engine); - } - - @Override - synchronized public long preallocate(){ - return super.preallocate(); - } - - @Override - synchronized public void preallocate(long[] recids){ - super.preallocate(recids); - } - - - @Override - synchronized public long put(A value, Serializer serializer) { - return super.put(value, serializer); - } - - @Override - synchronized public A get(long recid, Serializer serializer) { - return super.get(recid, serializer); - } - - @Override - synchronized public void update(long recid, A value, Serializer serializer) { - super.update(recid, value, serializer); - } - - @Override - synchronized public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - return super.compareAndSwap(recid, expectedOldValue, newValue, serializer); - } - - @Override - synchronized public void delete(long recid, Serializer serializer) { - super.delete(recid, serializer); - } - - @Override - synchronized public void close() { - super.close(); - } - - @Override - synchronized public boolean isClosed() { - return super.isClosed(); - } - - @Override - synchronized public void commit() { - super.commit(); - } - - @Override - synchronized public void rollback() { - super.rollback(); - } - - @Override - synchronized public boolean isReadOnly() { - return super.isReadOnly(); - } - - @Override - synchronized public boolean canSnapshot() { - return super.canSnapshot(); - } - - @Override - synchronized public Engine snapshot() throws UnsupportedOperationException { - return super.snapshot(); - } - - @Override - synchronized public void compact() { - super.compact(); - } - } - - - /** Checks that Serializer used to serialize item is the same as Serializer used to deserialize it*/ - public static class SerializerCheckEngineWrapper extends EngineWrapper{ - - protected LongMap recid2serializer = new LongConcurrentHashMap(); - - protected SerializerCheckEngineWrapper(Engine engine) { - super(engine); - } - - - synchronized protected void checkSerializer(long recid, Serializer serializer) { - Serializer other = recid2serializer.get(recid); - if(other!=null){ - if( other!=serializer && other.getClass()!=serializer.getClass()) - throw new IllegalArgumentException("Serializer does not match. \n found: "+serializer+" \n expected: "+other); - }else - recid2serializer.put(recid,serializer); - } - - @Override - public A get(long recid, Serializer serializer) { - checkSerializer(recid, serializer); - return super.get(recid, serializer); - } - - - @Override - public void update(long recid, A value, Serializer serializer) { - checkSerializer(recid, serializer); - super.update(recid, value, serializer); - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - checkSerializer(recid, serializer); - return super.compareAndSwap(recid, expectedOldValue, newValue, serializer); - } - - @Override - public void delete(long recid, Serializer serializer) { - checkSerializer(recid, serializer); - recid2serializer.remove(recid); - super.delete(recid, serializer); - } - } - - - /** throws `IllegalArgumentError("already closed)` on all access */ - public static final Engine CLOSED = new Engine(){ - - - @Override - public long preallocate() { - throw new IllegalAccessError("already closed"); - } - - @Override - public void preallocate(long[] recids) { - throw new IllegalAccessError("already closed"); - } - - @Override - public long put(A value, Serializer serializer) { - throw new IllegalAccessError("already closed"); - } - - @Override - public A get(long recid, Serializer serializer) { - throw new IllegalAccessError("already closed"); - } - - @Override - public void update(long recid, A value, Serializer serializer) { - throw new IllegalAccessError("already closed"); - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - throw new IllegalAccessError("already closed"); - } - - @Override - public void delete(long recid, Serializer serializer) { - throw new IllegalAccessError("already closed"); - } - - @Override - public void close() { - throw new IllegalAccessError("already closed"); - } - - @Override - public boolean isClosed() { - return true; - } - - @Override - public void commit() { - throw new IllegalAccessError("already closed"); - } - - @Override - public void rollback() throws UnsupportedOperationException { - throw new IllegalAccessError("already closed"); - } - - @Override - public boolean isReadOnly() { - throw new IllegalAccessError("already closed"); - } - - @Override - public boolean canRollback() { - throw new IllegalAccessError("already closed"); - } - - @Override - public boolean canSnapshot() { - throw new IllegalAccessError("already closed"); - } - - @Override - public Engine snapshot() throws UnsupportedOperationException { - throw new IllegalAccessError("already closed"); - } - - @Override - public void clearCache() { - throw new IllegalAccessError("already closed"); - } - - @Override - public void compact() { - throw new IllegalAccessError("already closed"); - } - - @Override - public SerializerPojo getSerializerPojo() { - throw new IllegalAccessError("already closed"); - } - - - }; - - /** - * Closes Engine on JVM shutdown using shutdown hook: {@link Runtime#addShutdownHook(Thread)} - * If engine was closed by user before JVM shutdown, hook is removed to save memory. - */ - public static class CloseOnJVMShutdown extends EngineWrapper{ - - final protected AtomicBoolean shutdownHappened = new AtomicBoolean(false); - - final Runnable hookRunnable = new Runnable() { - @Override - public void run() { - shutdownHappened.set(true); - CloseOnJVMShutdown.this.hook = null; - if(CloseOnJVMShutdown.this.isClosed()) - return; - CloseOnJVMShutdown.this.close(); - } - }; - - Thread hook; - - - public CloseOnJVMShutdown(Engine engine) { - super(engine); - hook = new Thread(hookRunnable,"MapDB shutdown hook"); - Runtime.getRuntime().addShutdownHook(hook); - } - - @Override - public void close() { - super.close(); - if(!shutdownHappened.get() && hook!=null){ - Runtime.getRuntime().removeShutdownHook(hook); - } - hook = null; - } - } -} diff --git a/src/main/java/org/mapdb/Fun.java b/src/main/java/org/mapdb/Fun.java deleted file mode 100644 index f65c826ca..000000000 --- a/src/main/java/org/mapdb/Fun.java +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.io.DataInput; -import java.io.IOException; -import java.io.Serializable; -import java.util.*; - -/** - * Functional stuff. Tuples, function, callback methods etc.. - * - * @author Jan Kotek - */ -public final class Fun { - - public static final Comparator COMPARATOR = new Comparator() { - @Override - public int compare(Comparable o1, Comparable o2) { - return o1.compareTo(o2); - } - }; - - public static final Comparator REVERSE_COMPARATOR = new Comparator() { - @Override - public int compare(Comparable o1, Comparable o2) { - return -COMPARATOR.compare(o1,o2); - } - }; - - - /** empty iterator (note: Collections.EMPTY_ITERATOR is Java 7 specific and should not be used)*/ - public static final Iterator EMPTY_ITERATOR = new ArrayList(0).iterator(); - - - private Fun(){} - - /** returns true if all elements are equal, works with nulls*/ - static public boolean eq(Object a, Object b) { - return a==b || (a!=null && a.equals(b)); - } - - /** Convert object to string, even if it is primitive array */ - static String toString(Object keys) { - if(keys instanceof long[]) - return Arrays.toString((long[]) keys); - else if(keys instanceof int[]) - return Arrays.toString((int[]) keys); - else if(keys instanceof byte[]) - return Arrays.toString((byte[]) keys); - else if(keys instanceof char[]) - return Arrays.toString((char[]) keys); - else if(keys instanceof float[]) - return Arrays.toString((float[]) keys); - else if(keys instanceof double[]) - return Arrays.toString((double[]) keys); - else if(keys instanceof boolean[]) - return Arrays.toString((boolean[]) keys); - else if(keys instanceof Object[]) - return Arrays.toString((Object[]) keys); - else - return keys.toString(); - } - - static public final class Pair implements Comparable>, Serializable { - - private static final long serialVersionUID = -8816277286657643283L; - - final public A a; - final public B b; - - public Pair(A a, B b) { - this.a = a; - this.b = b; - } - - /** constructor used for deserialization*/ - protected Pair(SerializerBase serializer, DataInput in, SerializerBase.FastArrayList objectStack) throws IOException { - objectStack.add(this); - this.a = (A) serializer.deserialize(in, objectStack); - this.b = (B) serializer.deserialize(in, objectStack); - } - - - @Override public int compareTo(Pair o) { - int i = ((Comparable)a).compareTo(o.a); - if(i!=0) - return i; - i = ((Comparable)b).compareTo(o.b); - return i; - - } - - @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final Pair t = (Pair) o; - - return eq(a,t.a) && eq(b,t.b); - } - - @Override public int hashCode() { - int result = a != null ? a.hashCode() : 0; - result = 31 * result + (b != null ? b.hashCode() : 0); - return result; - } - - @Override public String toString() { - return "Tuple2[" + a +", "+b+"]"; - } - - public void copyIntoArray(Object[] array, int offset) { - array[offset++] = a; - array[offset]=b; - } - - } - - /** - * Used to run background threads. - * Unlike {@link java.util.concurrent.ThreadFactory} it does not give access to threads, - * so tasks can run inside {@link java.util.concurrent.Executor}. - * - * There are some expectations from submitted tasks: - * - * * Background tasks is started within reasonable delay. You can not block if thread pool is full. - * That could cause memory leak since queues are not flushed etc.. - * - * * Runnable code might pause and call {@link Thread#sleep(long)}. - * - * * Threads must not be interrupted or terminated. Using daemon thread is forbidden. - * Runnable will exit itself, once db is closed. - * - */ - public interface ThreadFactory{ - - /** Basic thread factory which starts new thread for each runnable */ - public static final ThreadFactory BASIC = new ThreadFactory() { - @Override - public void newThread(String threadName, Runnable runnable) { - new Thread(runnable,threadName).start(); - } - }; - - /** execute new runnable. Optionally you can name thread using `threadName` argument */ - void newThread(String threadName, Runnable runnable); - } - - /** function which takes no argument and returns one value*/ - public interface Function0{ - R run(); - } - - /** function which takes one argument and returns one value*/ - public interface Function1{ - R run(A a); - } - - /** function which takes two argument and returns one value*/ - public interface Function2{ - R run(A a, B b); - } - - - public static Fun.Function1> extractKey(){ - return new Fun.Function1>() { - @Override - public K run(Pair t) { - return t.a; - } - }; - } - - public static Fun.Function1> extractValue(){ - return new Fun.Function1>() { - @Override - public V run(Pair t) { - return t.b; - } - }; - } - - - /** returns function which always returns the value itself without transformation */ - public static Function1 extractNoTransform() { - return new Function1() { - @Override - public K run(K k) { - return k; - } - }; - } - - - public static final Comparator BYTE_ARRAY_COMPARATOR = new Comparator() { - @Override - public int compare(byte[] o1, byte[] o2) { - if(o1==o2) return 0; - final int len = Math.min(o1.length,o2.length); - for(int i=0;io2[i]) - return 1; - return -1; - } - return compareInt(o1.length, o2.length); - } - }; - - - public static final Comparator CHAR_ARRAY_COMPARATOR = new Comparator() { - @Override - public int compare(char[] o1, char[] o2) { - if(o1==o2) return 0; - final int len = Math.min(o1.length,o2.length); - for(int i=0;io2[i]) - return 1; - return -1; - } - return compareInt(o1.length, o2.length); - } - }; - - public static final Comparator INT_ARRAY_COMPARATOR = new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - if(o1==o2) return 0; - final int len = Math.min(o1.length,o2.length); - for(int i=0;io2[i]) - return 1; - return -1; - } - return compareInt(o1.length, o2.length); - } - }; - - public static final Comparator LONG_ARRAY_COMPARATOR = new Comparator() { - @Override - public int compare(long[] o1, long[] o2) { - if(o1==o2) return 0; - final int len = Math.min(o1.length,o2.length); - for(int i=0;io2[i]) - return 1; - return -1; - } - return compareInt(o1.length, o2.length); - } - }; - - public static final Comparator DOUBLE_ARRAY_COMPARATOR = new Comparator() { - @Override - public int compare(double[] o1, double[] o2) { - if(o1==o2) return 0; - final int len = Math.min(o1.length,o2.length); - for(int i=0;io2[i]) - return 1; - return -1; - } - return compareInt(o1.length, o2.length); - } - }; - - - /** Compares two arrays which contains comparable elements */ - public static final Comparator COMPARABLE_ARRAY_COMPARATOR = new Comparator() { - @Override - public int compare(Object[] o1, Object[] o2) { - if(o1==o2) return 0; - final int len = Math.min(o1.length,o2.length); - for(int i=0;i{ - protected final Comparator[] comparators; - - public ArrayComparator(Comparator[] comparators2) { - this.comparators = comparators2.clone(); - for(int i=0;i objectStack) throws IOException { - objectStack.add(this); - this.comparators = (Comparator[]) serializer.deserialize(in, objectStack); - } - - - @Override - public int compare(Object[] o1, Object[] o2) { - if(o1==o2) return 0; - int len = Math.min(o1.length,o2.length); - for(int i=0;i filter(final NavigableSet set, final Object... keys) { - return new Iterable() { - @Override - public Iterator iterator() { - final Iterator iter = set.tailSet(keys).iterator(); - - if(!iter.hasNext()) - return Fun.EMPTY_ITERATOR; - - return new Iterator() { - - Object[] next = moveToNext(); - - Object[] moveToNext() { - if(!iter.hasNext()) - return null; - Object[] next = iter.next(); - if(next==null) - return null; - //check all elements are equal - //TODO this does not work if byte[] etc is used in array. Document or fail! - //TODO add special check for Fun.ARRAY comparator and use its sub-comparators - for(int i=0;i{ - boolean run(final long recid, final A value, final Serializer serializer); - } - - /** record condition which always returns true*/ - public static final RecordCondition RECORD_ALWAYS_TRUE = new RecordCondition() { - @Override - public boolean run(long recid, Object value, Serializer serializer) { - return true; - } - }; - - - -} diff --git a/src/main/java/org/mapdb/HTreeMap.java b/src/main/java/org/mapdb/HTreeMap.java deleted file mode 100644 index c2514377d..000000000 --- a/src/main/java/org/mapdb/HTreeMap.java +++ /dev/null @@ -1,1778 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ -package org.mapdb; - -import java.io.Closeable; -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.*; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Thread safe concurrent HashMap - *

- * This map uses full 32bit hash from beginning, There is no initial load factor and rehash. - * Technically it is not hash table, but hash tree with nodes expanding when they become full. - *

- * This map is suitable for number of records 1e9 and over. - * Larger number of records will increase hash collisions and performance - * will degrade linearly with number of records (separate chaining). - *

- * Concurrent scalability is achieved by splitting HashMap into 16 segments, each with separate lock. - * Very similar to {@link java.util.concurrent.ConcurrentHashMap} - * - * @author Jan Kotek - */ -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class HTreeMap extends AbstractMap implements ConcurrentMap, Bind.MapWithModificationListener, Closeable { - - protected static final Logger LOG = Logger.getLogger(HTreeMap.class.getName()); - - protected static final int BUCKET_OVERFLOW = 4; - - protected static final int DIV8 = 3; - protected static final int MOD8 = 0x7; - - /** is this a Map or Set? if false, entries do not have values, only keys are allowed*/ - protected final boolean hasValues; - - /** - * Salt added to hash before rehashing, so it is harder to trigger hash collision attack. - */ - protected final int hashSalt; - - protected final Atomic.Long counter; - - protected final Serializer keySerializer; - protected final Serializer valueSerializer; - protected final Hasher hasher; - - protected final Engine engine; - - protected final boolean expireFlag; - protected final long expireTimeStart; - protected final long expire; - protected final boolean expireAccessFlag; - protected final long expireAccess; - protected final long expireMaxSize; - protected final long expireStoreSize; - protected final boolean expireMaxSizeFlag; - - protected final long[] expireHeads; - protected final long[] expireTails; - - protected final Fun.Function1 valueCreator; - - protected boolean shutdown = false; - protected final CountDownLatch expirationThreadNum; - - - /** node which holds key-value pair */ - protected static final class LinkedNode{ - - public final long next; - public final long expireLinkNodeRecid; - - public final K key; - public final V value; - - public LinkedNode(final long next, long expireLinkNodeRecid, final K key, final V value ){ - this.key = key; - this.expireLinkNodeRecid = expireLinkNodeRecid; - this.value = value; - this.next = next; - } - } - - - - protected final Serializer> LN_SERIALIZER = new Serializer.Trusted>() { - - /** used to check that every 64000 th element has consistent has befor and after (de)serialization*/ - int serCounter = 0; - - @Override - public void serialize(DataOutput out, LinkedNode value) throws IOException { - if(((serCounter++ )& 0xFFFF)==0){ - assertHashConsistent(value.key); - } - - DataIO.packLong(out, value.next); - if(expireFlag) - DataIO.packLong(out, value.expireLinkNodeRecid); - keySerializer.serialize(out,value.key); - if(hasValues) - valueSerializer.serialize(out,value.value); - } - - @Override - public LinkedNode deserialize(DataInput in, int available) throws IOException { - if(CC.PARANOID && ! (available!=0)) - throw new AssertionError(); - return new LinkedNode( - DataIO.unpackLong(in), - expireFlag? DataIO.unpackLong(in):0L, - keySerializer.deserialize(in,-1), - hasValues? valueSerializer.deserialize(in,-1) : (V) BTreeMap.EMPTY - ); - } - - @Override - public int fixedSize() { - return -1; - } - - }; - - private final void assertHashConsistent(K key) throws IOException { - int hash = hasher.hashCode(key); - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - keySerializer.serialize(out,key); - DataIO.DataInputByteArray in = new DataIO.DataInputByteArray(out.buf, 0); - - K key2 = keySerializer.deserialize(in,-1); - if(hash!=hasher.hashCode(key2)){ - throw new IllegalArgumentException("Key does not have consistent hash before and after deserialization. Class: "+key.getClass()); - } - if(!hasher.equals(key,key2)){ - throw new IllegalArgumentException("Key does not have consistent equals before and after deserialization. Class: "+key.getClass()); - } - if(out.pos!=in.pos){ - throw new IllegalArgumentException("Key has inconsistent serialization length. Class: "+key.getClass()); - } - } - - - protected static final SerializerDIR_SERIALIZER = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, long[][] value) throws IOException { - if(CC.PARANOID && ! (value.length==16)) - throw new AssertionError(); - - //first write mask which indicate subarray nullability - int nulls = 0; - for(int i = 0;i<16;i++){ - if(value[i]!=null){ - for(long l:value[i]){ - if(l!=0){ - nulls |= 1<>>1; - } - - return ret; - } - - @Override - public int fixedSize() { - return -1; - } - - }; - - /** list of segments, this is immutable*/ - protected final long[] segmentRecids; - - protected final ReentrantReadWriteLock[] segmentLocks = new ReentrantReadWriteLock[16]; - { - for(int i=0;i< 16;i++) segmentLocks[i]=new ReentrantReadWriteLock(CC.FAIR_LOCKS); - } - - - - - /** - * Opens HTreeMap - */ - public HTreeMap(Engine engine, long counterRecid, int hashSalt, long[] segmentRecids, - Serializer keySerializer, Serializer valueSerializer, - long expireTimeStart, long expire, long expireAccess, long expireMaxSize, long expireStoreSize, - long[] expireHeads, long[] expireTails, Fun.Function1 valueCreator, - Hasher hasher, boolean disableLocks, Fun.ThreadFactory threadFactory) { - if(counterRecid<0) throw new IllegalArgumentException(); - if(engine==null) throw new NullPointerException(); - if(segmentRecids==null) throw new NullPointerException(); - if(keySerializer==null) throw new NullPointerException(); - -// SerializerBase.assertSerializable(keySerializer); //TODO serializer serialization - this.hasValues = valueSerializer!=null; - if(hasValues) { -// SerializerBase.assertSerializable(valueSerializer); - } - - - if(segmentRecids.length!=16) throw new IllegalArgumentException(); - - this.engine = engine; - this.hashSalt = hashSalt; - this.segmentRecids = Arrays.copyOf(segmentRecids,16); - this.keySerializer = keySerializer; - this.valueSerializer = valueSerializer; - this.hasher = hasher!=null ? hasher : Hasher.BASIC; - if(expire==0 && expireAccess!=0){ - expire = expireAccess; - } - if(expireMaxSize!=0 && counterRecid==0){ - throw new IllegalArgumentException("expireMaxSize must have counter enabled"); - } - - - this.expireFlag = expire !=0L || expireAccess!=0L || expireMaxSize!=0 || expireStoreSize!=0; - this.expire = expire; - this.expireTimeStart = expireTimeStart; - this.expireAccessFlag = expireAccess !=0L || expireMaxSize!=0 || expireStoreSize!=0; - this.expireAccess = expireAccess; - this.expireHeads = expireHeads==null? null : Arrays.copyOf(expireHeads,16); - this.expireTails = expireTails==null? null : Arrays.copyOf(expireTails,16); - this.expireMaxSizeFlag = expireMaxSize!=0; - this.expireMaxSize = expireMaxSize; - this.expireStoreSize = expireStoreSize; - this.valueCreator = valueCreator; - - if(counterRecid!=0){ - this.counter = new Atomic.Long(engine,counterRecid); - Bind.size(this,counter); - }else{ - this.counter = null; - } - - if(expireFlag){ - expirationThreadNum = new CountDownLatch(1); - threadFactory.newThread("HTreeMap expirator", new ExpireRunnable(this)); - }else{ - expirationThreadNum = null; - } - - } - - - - protected static long[] preallocateSegments(Engine engine){ - //prealocate segmentRecids, so we dont have to lock on those latter - long[] ret = new long[16]; - for(int i=0;i<16;i++) - ret[i] = engine.put(new long[16][], DIR_SERIALIZER); - return ret; - } - - - - @Override - public boolean containsKey(final Object o){ - return getPeek(o)!=null; - } - - @Override - public int size() { - long size = sizeLong(); - if(size>Integer.MAX_VALUE) return Integer.MAX_VALUE; - return (int) size; - } - - - @Override - public long sizeLong() { - if(counter!=null) - return counter.get(); - - - long counter = 0; - - //search tree, until we find first non null - for(int i=0;i<16;i++){ - try{ - segmentLocks[i].readLock().lock(); - - final long dirRecid = segmentRecids[i]; - counter+=recursiveDirCount(dirRecid); - }finally { - segmentLocks[i].readLock().unlock(); - } - } - - - return counter; - } - - private long recursiveDirCount(final long dirRecid) { - long[][] dir = engine.get(dirRecid, DIR_SERIALIZER); - long counter = 0; - for(long[] subdir:dir){ - if(subdir == null) continue; - for(long recid:subdir){ - if(recid == 0) continue; - if((recid&1)==0){ - //reference to another subdir - recid = recid>>>1; - counter += recursiveDirCount(recid); - }else{ - //reference to linked list, count it - recid = recid>>>1; - while(recid!=0){ - LinkedNode n = engine.get(recid, LN_SERIALIZER); - if(n!=null){ - counter++; - recid = n.next; - }else{ - recid = 0; - } - } - } - } - } - return counter; - } - - @Override - public boolean isEmpty() { - //search tree, until we find first non null - for(int i=0;i<16;i++){ - try{ - segmentLocks[i].readLock().lock(); - - long dirRecid = segmentRecids[i]; - long[][] dir = engine.get(dirRecid, DIR_SERIALIZER); - for(long[] d:dir){ - if(d!=null) return false; - } - - }finally { - segmentLocks[i].readLock().unlock(); - } - } - - return true; - } - - - - @Override - public V get(final Object o){ - if(o==null) return null; - final int h = hash(o); - final int segment = h >>>28; - - final Lock lock = expireAccessFlag ? segmentLocks[segment].writeLock() : segmentLocks[segment].readLock(); - lock.lock(); - LinkedNode ln; - try{ - ln = getInner(o, h, segment); - - if(ln!=null && expireAccessFlag) - expireLinkBump(segment,ln.expireLinkNodeRecid,true); - }finally { - lock.unlock(); - } - if(valueCreator==null){ - if(ln==null) - return null; - return ln.value; - } - - //value creator is set, so create and put new value - V value = valueCreator.run((K) o); - //there is race condition, vc could be called twice. But map will be updated only once - V prevVal = putIfAbsent((K) o,value); - if(prevVal!=null) - return prevVal; - return value; - } - - - /** - * Return given value, without updating cache statistics if `expireAccess()` is true - * It also does not use `valueCreator` if value is not found (always returns null if not found) - * - * @param key key to lookup - * @return value associated with key or null - */ - public V getPeek(final Object key){ - if(key==null) return null; - final int h = hash(key); - final int segment = h >>>28; - - final Lock lock = segmentLocks[segment].readLock(); - lock.lock(); - - try{ - LinkedNode ln = getInner(key, h, segment); - if(ln==null) return null; - return ln.value; - }finally { - lock.unlock(); - } - - } - - protected LinkedNode getInner(Object o, int h, int segment) { - long recid = segmentRecids[segment]; - for(int level=3;level>=0;level--){ - long[][] dir = engine.get(recid, DIR_SERIALIZER); - if(dir == null) return null; - final int slot = (h>>>(level*7 )) & 0x7F; - if(CC.PARANOID && ! (slot<128)) - throw new AssertionError(); - final int slotDiv8 = slot >>> DIV8; - if(dir[slotDiv8]==null) return null; - recid = dir[slotDiv8][slot&MOD8]; - if(recid == 0) return null; - if((recid&1)!=0){ //last bite indicates if referenced record is LinkedNode - recid = recid>>>1; - while(true){ - LinkedNode ln = engine.get(recid, LN_SERIALIZER); - if(ln == null) return null; - if(hasher.equals(ln.key, (K) o)){ - if(CC.PARANOID && ! (hash(ln.key)==h)) - throw new AssertionError(); - return ln; - } - if(ln.next==0) return null; - recid = ln.next; - } - } - - recid = recid>>>1; - } - - return null; - } - - @Override - public V put(final K key, final V value){ - if (key == null) - throw new IllegalArgumentException("null key"); - - if (value == null) - throw new IllegalArgumentException("null value"); - - final int h = hash(key); - final int segment = h >>>28; - segmentLocks[segment].writeLock().lock(); - try{ - - return putInner(key, value, h, segment); - - }finally { - segmentLocks[segment].writeLock().unlock(); - } - } - - private V putInner(K key, V value, int h, int segment) { - long dirRecid = segmentRecids[segment]; - - int level = 3; - while(true){ - long[][] dir = engine.get(dirRecid, DIR_SERIALIZER); - final int slot = (h>>>(7*level )) & 0x7F; - final int slotDiv8 = slot >>> DIV8; - if(CC.PARANOID && ! (slot<=127)) - throw new AssertionError(); - - if(dir == null ){ - //create new dir - dir = new long[16][]; - } - - if(dir[slotDiv8] == null){ - dir = Arrays.copyOf(dir, 16); - dir[slotDiv8] = new long[8]; - } - - int counter = 0; - long recid = dir[slotDiv8][slot&MOD8]; - - if(recid!=0){ - if((recid&1) == 0){ - dirRecid = recid>>>1; - level--; - continue; - } - recid = recid>>>1; - - //traverse linked list, try to replace previous value - LinkedNode ln = engine.get(recid, LN_SERIALIZER); - - while(ln!=null){ - if(hasher.equals(ln.key,key)){ - //found, replace value at this node - V oldVal = ln.value; - ln = new LinkedNode(ln.next, ln.expireLinkNodeRecid, ln.key, value); - engine.update(recid, ln, LN_SERIALIZER); - if(expireFlag) expireLinkBump(segment,ln.expireLinkNodeRecid,false); - notify(key, oldVal, value); - return oldVal; - } - recid = ln.next; - ln = recid==0? null : engine.get(recid, LN_SERIALIZER); - counter++; - } - //key was not found at linked list, so just append it to beginning - } - - - //check if linked list has overflow and needs to be expanded to new dir level - if(counter>=BUCKET_OVERFLOW && level>=1){ - long[][] nextDir = new long[16][]; - - { - final long expireNodeRecid = expireFlag? engine.preallocate():0L; - final LinkedNode node = new LinkedNode(0, expireNodeRecid, key, value); - final long newRecid = engine.put(node, LN_SERIALIZER); - //add newly inserted record - final int pos =(h >>>(7*(level-1) )) & 0x7F; - final int posDiv8 = pos >>> DIV8; - nextDir[posDiv8] = new long[8]; - nextDir[posDiv8][pos&MOD8] = ( newRecid<<1) | 1; - if(expireFlag) expireLinkAdd(segment,expireNodeRecid,newRecid,h); - } - - - //redistribute linked bucket into new dir - long nodeRecid = dir[slotDiv8][slot&MOD8]>>>1; - while(nodeRecid!=0){ - LinkedNode n = engine.get(nodeRecid, LN_SERIALIZER); - final long nextRecid = n.next; - final int pos = (hash(n.key) >>>(7*(level -1) )) & 0x7F; - final int posDiv8 = pos >>> DIV8; - final int posMod8 = pos & MOD8; - if(nextDir[posDiv8]==null) - nextDir[posDiv8] = new long[8]; - n = new LinkedNode(nextDir[posDiv8][posMod8]>>>1, n.expireLinkNodeRecid, n.key, n.value); - nextDir[posDiv8][posMod8] = (nodeRecid<<1) | 1; - engine.update(nodeRecid, n, LN_SERIALIZER); - nodeRecid = nextRecid; - } - - //insert nextDir and update parent dir - long nextDirRecid = engine.put(nextDir, DIR_SERIALIZER); - int parentPos = (h>>>(7*level )) & 0x7F; - dir = Arrays.copyOf(dir,16); - int parentPosDiv8 = parentPos >>> DIV8; - dir[parentPosDiv8] = Arrays.copyOf(dir[parentPosDiv8],8); - dir[parentPosDiv8][parentPos&MOD8] = (nextDirRecid<<1) | 0; - engine.update(dirRecid, dir, DIR_SERIALIZER); - notify(key, null, value); - return null; - }else{ - // record does not exist in linked list, so create new one - recid = dir[slotDiv8][slot&MOD8]>>>1; - final long expireNodeRecid = expireFlag? engine.put(ExpireLinkNode.EMPTY, ExpireLinkNode.SERIALIZER):0L; - - final long newRecid = engine.put(new LinkedNode(recid, expireNodeRecid, key, value), LN_SERIALIZER); - dir = Arrays.copyOf(dir,16); - dir[slotDiv8] = Arrays.copyOf(dir[slotDiv8],8); - dir[slotDiv8][slot&MOD8] = (newRecid<<1) | 1; - engine.update(dirRecid, dir, DIR_SERIALIZER); - if(expireFlag) expireLinkAdd(segment,expireNodeRecid, newRecid,h); - notify(key, null, value); - return null; - } - } - } - - - @Override - public V remove(Object key){ - - final int h = hash(key); - final int segment = h >>>28; - segmentLocks[segment].writeLock().lock(); - try{ - return removeInternal(key, segment, h, true); - }finally { - segmentLocks[segment].writeLock().unlock(); - } - } - - - protected V removeInternal(Object key, int segment, int h, boolean removeExpire){ - final long[] dirRecids = new long[4]; - int level = 3; - dirRecids[level] = segmentRecids[segment]; - - if(CC.PARANOID && ! (segment==h>>>28)) - throw new AssertionError(); - - while(true){ - long[][] dir = engine.get(dirRecids[level], DIR_SERIALIZER); - final int slot = (h>>>(7*level )) & 0x7F; - if(CC.PARANOID && ! (slot<=127)) - throw new AssertionError(); - - if(dir == null ){ - //create new dir - dir = new long[16][]; - } - - final int slotDiv8 = slot >>> DIV8; - if(dir[slotDiv8] == null){ - dir = Arrays.copyOf(dir,16); - dir[slotDiv8] = new long[8]; - } - -// int counter = 0; - final int slotMod8 = slot & MOD8; - long recid = dir[slotDiv8][slotMod8]; - - if(recid!=0){ - if((recid&1) == 0){ - level--; - dirRecids[level] = recid>>>1; - continue; - } - recid = recid>>>1; - - //traverse linked list, try to remove node - LinkedNode ln = engine.get(recid, LN_SERIALIZER); - LinkedNode prevLn = null; - long prevRecid = 0; - while(ln!=null){ - if(hasher.equals(ln.key, (K) key)){ - //remove from linkedList - if(prevLn == null ){ - //referenced directly from dir - if(ln.next==0){ - recursiveDirDelete(h, level, dirRecids, dir, slot); - - - }else{ - dir=Arrays.copyOf(dir,16); - dir[slotDiv8] = Arrays.copyOf(dir[slotDiv8],8); - dir[slotDiv8][slotMod8] = (ln.next<<1)|1; - engine.update(dirRecids[level], dir, DIR_SERIALIZER); - } - - }else{ - //referenced from LinkedNode - prevLn = new LinkedNode(ln.next, prevLn.expireLinkNodeRecid,prevLn.key, prevLn.value); - engine.update(prevRecid, prevLn, LN_SERIALIZER); - } - //found, remove this node - if(CC.PARANOID && ! (hash(ln.key)==h)) - throw new AssertionError(); - engine.delete(recid, LN_SERIALIZER); - if(removeExpire && expireFlag) expireLinkRemove(segment, ln.expireLinkNodeRecid); - notify((K) key, ln.value, null); - return ln.value; - } - prevRecid = recid; - prevLn = ln; - recid = ln.next; - ln = recid==0? null : engine.get(recid, LN_SERIALIZER); -// counter++; - } - //key was not found at linked list, so it does not exist - return null; - } - //recid is 0, so entry does not exist - return null; - - } - } - - - private void recursiveDirDelete(int h, int level, long[] dirRecids, long[][] dir, int slot) { - //was only item in linked list, so try to collapse the dir - dir=Arrays.copyOf(dir,16); - dir[slot>>>DIV8] = Arrays.copyOf(dir[slot>>>DIV8],8); - dir[slot>>>DIV8][slot&MOD8] = 0; - //one record was zeroed out, check if subarray can be collapsed to null - boolean allZero = true; - for(long l:dir[slot>>>DIV8]){ - if(l!=0){ - allZero = false; - break; - } - } - if(allZero){ - dir[slot>>>DIV8] = null; - } - allZero = true; - for(long[] l:dir){ - if(l!=null){ - allZero = false; - break; - } - } - - if(allZero){ - //delete from parent dir - if(level==3){ - //parent is segment, recid of this dir can not be modified, so just update to null - engine.update(dirRecids[level], new long[16][], DIR_SERIALIZER); - }else{ - engine.delete(dirRecids[level], DIR_SERIALIZER); - - final long[][] parentDir = engine.get(dirRecids[level + 1], DIR_SERIALIZER); - final int parentPos = (h >>> (7 * (level + 1))) & 0x7F; - recursiveDirDelete(h,level+1,dirRecids, parentDir, parentPos); - //parentDir[parentPos>>>DIV8][parentPos&MOD8] = 0; - //engine.update(dirRecids[level + 1],parentDir,DIR_SERIALIZER); - - } - }else{ - engine.update(dirRecids[level], dir, DIR_SERIALIZER); - } - } - - @Override - public void clear() { - for(int i = 0; i<16;i++) try{ - segmentLocks[i].writeLock().lock(); - - final long dirRecid = segmentRecids[i]; - recursiveDirClear(dirRecid); - - //set dir to null, as segment recid is immutable - engine.update(dirRecid, new long[16][], DIR_SERIALIZER); - - if(expireFlag) - while(expireLinkRemoveLast(i)!=null){} //TODO speedup remove all - - }finally { - segmentLocks[i].writeLock().unlock(); - } - } - - private void recursiveDirClear(final long dirRecid) { - final long[][] dir = engine.get(dirRecid, DIR_SERIALIZER); - if(dir == null) return; - for(long[] subdir:dir){ - if(subdir==null) continue; - for(long recid:subdir){ - if(recid == 0) continue; - if((recid&1)==0){ - //another dir - recid = recid>>>1; - //recursively remove dir - recursiveDirClear(recid); - engine.delete(recid, DIR_SERIALIZER); - }else{ - //linked list to delete - recid = recid>>>1; - while(recid!=0){ - LinkedNode n = engine.get(recid, LN_SERIALIZER); - engine.delete(recid,LN_SERIALIZER); - notify((K)n.key, (V)n.value , null); - recid = n.next; - } - } - - } - } - } - - - @Override - public boolean containsValue(Object value) { - for (V v : values()) { - if (v.equals(value)) return true; - } - return false; - } - - - - protected class KeySet extends AbstractSet { - - @Override - public int size() { - return HTreeMap.this.size(); - } - - @Override - public boolean isEmpty() { - return HTreeMap.this.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return HTreeMap.this.containsKey(o); - } - - @Override - public Iterator iterator() { - return new KeyIterator(); - } - - @Override - public boolean add(K k) { - if(HTreeMap.this.hasValues) - throw new UnsupportedOperationException(); - else - return HTreeMap.this.put(k, (V) BTreeMap.EMPTY) == null; - } - - @Override - public boolean remove(Object o) { -// if(o instanceof Entry){ -// Entry e = (Entry) o; -// return HTreeMap.this.remove(((Entry) o).getKey(),((Entry) o).getValue()); -// } - return HTreeMap.this.remove(o)!=null; - - } - - - @Override - public void clear() { - HTreeMap.this.clear(); - } - - public HTreeMap parent(){ - return HTreeMap.this; - } - - @Override - public int hashCode() { - int result = 0; - for (K k : this) { - result += hasher.hashCode(k); - } - return result; - - } - } - - - - private final Set _keySet = new KeySet(); - - @Override - public Set keySet() { - return _keySet; - } - - private final Collection _values = new AbstractCollection(){ - - @Override - public int size() { - return HTreeMap.this.size(); - } - - @Override - public boolean isEmpty() { - return HTreeMap.this.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return HTreeMap.this.containsValue(o); - } - - - - @Override - public Iterator iterator() { - return new ValueIterator(); - } - - }; - - @Override - public Collection values() { - return _values; - } - - private final Set> _entrySet = new AbstractSet>(){ - - @Override - public int size() { - return HTreeMap.this.size(); - } - - @Override - public boolean isEmpty() { - return HTreeMap.this.isEmpty(); - } - - @Override - public boolean contains(Object o) { - if(o instanceof Entry){ - Entry e = (Entry) o; - Object val = HTreeMap.this.get(e.getKey()); - return val!=null && val.equals(e.getValue()); - }else - return false; - } - - @Override - public Iterator> iterator() { - return new EntryIterator(); - } - - - @Override - public boolean add(Entry kvEntry) { - K key = kvEntry.getKey(); - V value = kvEntry.getValue(); - if(key==null || value == null) throw new NullPointerException(); - HTreeMap.this.put(key, value); - return true; - } - - @Override - public boolean remove(Object o) { - if(o instanceof Entry){ - Entry e = (Entry) o; - Object key = e.getKey(); - if(key == null) return false; - return HTreeMap.this.remove(key, e.getValue()); - } - return false; - } - - - @Override - public void clear() { - HTreeMap.this.clear(); - } - }; - - @Override - public Set> entrySet() { - return _entrySet; - } - - - protected int hash(final Object key) { - int h = hasher.hashCode((K) key) ^ hashSalt; - h ^= (h >>> 20) ^ (h >>> 12); - return h ^ (h >>> 7) ^ (h >>> 4); - } - - - abstract class HashIterator{ - - protected LinkedNode[] currentLinkedList; - protected int currentLinkedListPos = 0; - - private K lastReturnedKey = null; - - private int lastSegment = 0; - - HashIterator(){ - currentLinkedList = findNextLinkedNode(0); - } - - public void remove() { - final K keyToRemove = lastReturnedKey; - if (lastReturnedKey == null) - throw new IllegalStateException(); - - lastReturnedKey = null; - HTreeMap.this.remove(keyToRemove); - } - - public boolean hasNext(){ - return currentLinkedList!=null && currentLinkedListPos>>28; - - //two phases, first find old item and increase hash - try{ - segmentLocks[segment].readLock().lock(); - - long dirRecid = segmentRecids[segment]; - int level = 3; - //dive into tree, finding last hash position - while(true){ - long[][] dir = engine.get(dirRecid, DIR_SERIALIZER); - final int pos = (lastHash>>>(7 * level)) & 0x7F; - - //check if we need to expand deeper - final int posDiv8 = pos >>> DIV8; - final int posMod8 = pos & MOD8; - if(dir[posDiv8]==null || dir[posDiv8][posMod8]==0 || (dir[posDiv8][posMod8]&1)==1) { - //increase hash by 1 - if(level!=0){ - lastHash = ((lastHash>>>(7 * level)) + 1) << (7*level); //should use mask and XOR - }else - lastHash +=1; - if(lastHash==0){ - return null; - } - break; - } - - //reference is dir, move to next level - dirRecid = dir[posDiv8][posMod8]>>>1; - level--; - } - - }finally { - segmentLocks[segment].readLock().unlock(); - } - return findNextLinkedNode(lastHash); - - - } - - private LinkedNode[] findNextLinkedNode(int hash) { - //second phase, start search from increased hash to find next items - for(int segment = Math.max(hash >>>28, lastSegment); segment<16;segment++){ - final Lock lock = expireAccessFlag ? segmentLocks[segment].writeLock() :segmentLocks[segment].readLock() ; - lock.lock(); - try{ - lastSegment = Math.max(segment,lastSegment); - long dirRecid = segmentRecids[segment]; - LinkedNode ret[] = findNextLinkedNodeRecur(dirRecid, hash, 3); - if(CC.PARANOID && ret!=null) for(LinkedNode ln:ret){ - if(( hash(ln.key)>>>28!=segment)) - throw new AssertionError(); - } - //System.out.println(Arrays.asList(ret)); - if(ret !=null){ - if(expireAccessFlag){ - for(LinkedNode ln:ret) expireLinkBump(segment,ln.expireLinkNodeRecid,true); - } - return ret; - } - hash = 0; - }finally { - lock.unlock(); - } - } - - return null; - } - - private LinkedNode[] findNextLinkedNodeRecur(long dirRecid, int newHash, int level){ - long[][] dir = engine.get(dirRecid, DIR_SERIALIZER); - if(dir == null) return null; - int pos = (newHash>>>(level*7)) & 0x7F; - boolean first = true; - while(pos<128){ - if(dir[pos>>>DIV8]!=null){ - long recid = dir[pos>>>DIV8][pos&MOD8]; - if(recid!=0){ - if((recid&1) == 1){ - recid = recid>>1; - //found linked list, load it into array and return - LinkedNode[] array = new LinkedNode[1]; - int arrayPos = 0; - while(recid!=0){ - LinkedNode ln = engine.get(recid, LN_SERIALIZER); - if(ln==null){ - recid = 0; - continue; - } - //increase array size if needed - if(arrayPos == array.length) - array = Arrays.copyOf(array, array.length+1); - array[arrayPos++] = ln; - recid = ln.next; - } - return array; - }else{ - //found another dir, continue dive - recid = recid>>1; - LinkedNode[] ret = findNextLinkedNodeRecur(recid, first ? newHash : 0, level - 1); - if(ret != null) return ret; - } - } - } - first = false; - pos++; - } - return null; - } - } - - class KeyIterator extends HashIterator implements Iterator{ - - @Override - public K next() { - if(currentLinkedList == null) - throw new NoSuchElementException(); - K key = (K) currentLinkedList[currentLinkedListPos].key; - moveToNext(); - return key; - } - } - - class ValueIterator extends HashIterator implements Iterator{ - - @Override - public V next() { - if(currentLinkedList == null) - throw new NoSuchElementException(); - V value = (V) currentLinkedList[currentLinkedListPos].value; - moveToNext(); - return value; - } - } - - class EntryIterator extends HashIterator implements Iterator>{ - - @Override - public Entry next() { - if(currentLinkedList == null) - throw new NoSuchElementException(); - K key = (K) currentLinkedList[currentLinkedListPos].key; - moveToNext(); - return new Entry2(key); - } - } - - class Entry2 implements Entry{ - - private final K key; - - Entry2(K key) { - this.key = key; - } - - @Override - public K getKey() { - return key; - } - - @Override - public V getValue() { - return HTreeMap.this.get(key); - } - - @Override - public V setValue(V value) { - return HTreeMap.this.put(key,value); - } - - @Override - public boolean equals(Object o) { - return (o instanceof Entry) && hasher.equals(key, (K) ((Entry) o).getKey()); - } - - @Override - public int hashCode() { - final V value = HTreeMap.this.get(key); - return (key == null ? 0 : hasher.hashCode(key)) ^ - (value == null ? 0 : value.hashCode()); - } - } - - - @Override - public V putIfAbsent(K key, V value) { - if(key==null||value==null) throw new NullPointerException(); - - final int h = HTreeMap.this.hash(key); - final int segment = h >>>28; - try{ - segmentLocks[segment].writeLock().lock(); - - LinkedNode ln = HTreeMap.this.getInner(key,h,segment); - if (ln==null) - return put(key, value); - else - return ln.value; - - }finally { - segmentLocks[segment].writeLock().unlock(); - } - } - - @Override - public boolean remove(Object key, Object value) { - if(key==null||value==null) throw new NullPointerException(); - final int h = HTreeMap.this.hash(key); - final int segment = h >>>28; - try{ - segmentLocks[segment].writeLock().lock(); - - LinkedNode otherVal = getInner(key, h, segment); - if (otherVal!=null && otherVal.value.equals(value)) { - removeInternal(key, segment, h, true); - return true; - }else - return false; - - }finally { - segmentLocks[segment].writeLock().unlock(); - } - } - - @Override - public boolean replace(K key, V oldValue, V newValue) { - if(key==null||oldValue==null||newValue==null) throw new NullPointerException(); - final int h = HTreeMap.this.hash(key); - final int segment = h >>>28; - try{ - segmentLocks[segment].writeLock().lock(); - - LinkedNode ln = getInner(key, h,segment); - if (ln!=null && ln.value.equals(oldValue)) { - putInner(key, newValue,h,segment); - return true; - } else - return false; - - }finally { - segmentLocks[segment].writeLock().unlock(); - } - } - - @Override - public V replace(K key, V value) { - if(key==null||value==null) throw new NullPointerException(); - final int h = HTreeMap.this.hash(key); - final int segment = h >>>28; - try{ - segmentLocks[segment].writeLock().lock(); - - if (getInner(key,h,segment)!=null) - return putInner(key, value,h,segment); - else - return null; - }finally { - segmentLocks[segment].writeLock().unlock(); - } - } - - - - protected static final class ExpireLinkNode{ - - public final static ExpireLinkNode EMPTY = new ExpireLinkNode(0,0,0,0,0); - - public static final Serializer SERIALIZER = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, ExpireLinkNode value) throws IOException { - if(value == EMPTY) return; - DataIO.packLong(out, value.prev); - DataIO.packLong(out, value.next); - DataIO.packLong(out, value.keyRecid); - DataIO.packLong(out, value.time); - out.writeInt(value.hash); - } - - @Override - public ExpireLinkNode deserialize(DataInput in, int available) throws IOException { - if(available==0) return EMPTY; - return new ExpireLinkNode( - DataIO.unpackLong(in), DataIO.unpackLong(in), DataIO.unpackLong(in), DataIO.unpackLong(in), - in.readInt() - ); - } - - @Override - public int fixedSize() { - return -1; - } - - }; - - public final long prev; - public final long next; - public final long keyRecid; - public final long time; - public final int hash; - - public ExpireLinkNode(long prev, long next, long keyRecid, long time, int hash) { - this.prev = prev; - this.next = next; - this.keyRecid = keyRecid; - this.time = time; - this.hash = hash; - } - - public ExpireLinkNode copyNext(long next2) { - return new ExpireLinkNode(prev,next2, keyRecid,time,hash); - } - - public ExpireLinkNode copyPrev(long prev2) { - return new ExpireLinkNode(prev2,next, keyRecid,time,hash); - } - - public ExpireLinkNode copyTime(long time2) { - return new ExpireLinkNode(prev,next,keyRecid,time2,hash); - } - - } - - - - protected void expireLinkAdd(int segment, long expireNodeRecid, long keyRecid, int hash){ - if(CC.PARANOID && ! (segmentLocks[segment].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); - if(CC.PARANOID && ! (expireNodeRecid>0)) - throw new AssertionError(); - if(CC.PARANOID && ! (keyRecid>0)) - throw new AssertionError(); - - long time = expire==0 ? 0: expire+System.currentTimeMillis()-expireTimeStart; - long head = engine.get(expireHeads[segment],Serializer.LONG); - if(head == 0){ - //insert new - ExpireLinkNode n = new ExpireLinkNode(0,0,keyRecid,time,hash); - engine.update(expireNodeRecid, n, ExpireLinkNode.SERIALIZER); - engine.update(expireHeads[segment],expireNodeRecid,Serializer.LONG); - engine.update(expireTails[segment],expireNodeRecid,Serializer.LONG); - }else{ - //insert new head - ExpireLinkNode n = new ExpireLinkNode(head,0,keyRecid,time,hash); - engine.update(expireNodeRecid, n, ExpireLinkNode.SERIALIZER); - - //update old head to have new head as next - ExpireLinkNode oldHead = engine.get(head,ExpireLinkNode.SERIALIZER); - oldHead=oldHead.copyNext(expireNodeRecid); - engine.update(head,oldHead,ExpireLinkNode.SERIALIZER); - - //and update head - engine.update(expireHeads[segment],expireNodeRecid,Serializer.LONG); - } - } - - protected void expireLinkBump(int segment, long nodeRecid, boolean access){ - if(CC.PARANOID && ! (segmentLocks[segment].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); - - ExpireLinkNode n = engine.get(nodeRecid,ExpireLinkNode.SERIALIZER); - long newTime = - access? - (expireAccess==0?0 : expireAccess+System.currentTimeMillis()-expireTimeStart): - (expire==0?0 : expire+System.currentTimeMillis()-expireTimeStart); - - //TODO optimize bellow, but what if there is only size limit? - //if(n.time>newTime) return; // older time greater than new one, do not update - - if(n.next==0){ - //already head, so just update time - n = n.copyTime(newTime); - engine.update(nodeRecid,n,ExpireLinkNode.SERIALIZER); - }else{ - //update prev so it points to next - if(n.prev!=0){ - //not a tail - ExpireLinkNode prev = engine.get(n.prev,ExpireLinkNode.SERIALIZER); - prev=prev.copyNext(n.next); - engine.update(n.prev, prev, ExpireLinkNode.SERIALIZER); - }else{ - //yes tail, so just update it to point to next - engine.update(expireTails[segment],n.next,Serializer.LONG); - } - - //update next so it points to prev - ExpireLinkNode next = engine.get(n.next, ExpireLinkNode.SERIALIZER); - next=next.copyPrev(n.prev); - engine.update(n.next,next,ExpireLinkNode.SERIALIZER); - - //TODO optimize if oldHead==next - - //now insert node as new head - long oldHeadRecid = engine.get(expireHeads[segment],Serializer.LONG); - ExpireLinkNode oldHead = engine.get(oldHeadRecid, ExpireLinkNode.SERIALIZER); - oldHead = oldHead.copyNext(nodeRecid); - engine.update(oldHeadRecid,oldHead,ExpireLinkNode.SERIALIZER); - engine.update(expireHeads[segment],nodeRecid,Serializer.LONG); - - n = new ExpireLinkNode(oldHeadRecid,0, n.keyRecid, newTime, n.hash); - engine.update(nodeRecid,n,ExpireLinkNode.SERIALIZER); - } - } - - protected ExpireLinkNode expireLinkRemoveLast(int segment){ - if(CC.PARANOID && ! (segmentLocks[segment].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); - - long tail = engine.get(expireTails[segment],Serializer.LONG); - if(tail==0) return null; - - ExpireLinkNode n = engine.get(tail,ExpireLinkNode.SERIALIZER); - if(n.next==0){ - //update tail and head - engine.update(expireHeads[segment],0L,Serializer.LONG); - engine.update(expireTails[segment],0L,Serializer.LONG); - }else{ - //point tail to next record - engine.update(expireTails[segment],n.next,Serializer.LONG); - //update next record to have zero prev - ExpireLinkNode next = engine.get(n.next,ExpireLinkNode.SERIALIZER); - next=next.copyPrev(0L); - engine.update(n.next, next, ExpireLinkNode.SERIALIZER); - } - - engine.delete(tail,ExpireLinkNode.SERIALIZER); - return n; - } - - - protected ExpireLinkNode expireLinkRemove(int segment, long nodeRecid){ - if(CC.PARANOID && ! (segmentLocks[segment].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); - - ExpireLinkNode n = engine.get(nodeRecid,ExpireLinkNode.SERIALIZER); - engine.delete(nodeRecid,ExpireLinkNode.SERIALIZER); - if(n.next == 0 && n.prev==0){ - engine.update(expireHeads[segment],0L,Serializer.LONG); - engine.update(expireTails[segment],0L,Serializer.LONG); - }else if (n.next == 0) { - ExpireLinkNode prev = engine.get(n.prev,ExpireLinkNode.SERIALIZER); - prev=prev.copyNext(0); - engine.update(n.prev,prev,ExpireLinkNode.SERIALIZER); - engine.update(expireHeads[segment],n.prev,Serializer.LONG); - }else if (n.prev == 0) { - ExpireLinkNode next = engine.get(n.next,ExpireLinkNode.SERIALIZER); - next=next.copyPrev(0); - engine.update(n.next,next,ExpireLinkNode.SERIALIZER); - engine.update(expireTails[segment],n.next,Serializer.LONG); - }else{ - ExpireLinkNode next = engine.get(n.next,ExpireLinkNode.SERIALIZER); - next=next.copyPrev(n.prev); - engine.update(n.next,next,ExpireLinkNode.SERIALIZER); - - ExpireLinkNode prev = engine.get(n.prev,ExpireLinkNode.SERIALIZER); - prev=prev.copyNext(n.next); - engine.update(n.prev,prev,ExpireLinkNode.SERIALIZER); - } - - return n; - } - - /** - * Returns maximal (newest) expiration timestamp - */ - public long getMaxExpireTime(){ - if(!expireFlag) return 0; - long ret = 0; - for(int segment = 0;segment<16;segment++){ - segmentLocks[segment].readLock().lock(); - try{ - long head = engine.get(expireHeads[segment],Serializer.LONG); - if(head == 0) continue; - ExpireLinkNode ln = engine.get(head, ExpireLinkNode.SERIALIZER); - if(ln==null || ln.time==0) continue; - ret = Math.max(ret, ln.time+expireTimeStart); - }finally{ - segmentLocks[segment].readLock().unlock(); - } - } - return ret; - } - - /** - * Returns minimal (oldest) expiration timestamp - */ - public long getMinExpireTime(){ - if(!expireFlag) return 0; - long ret = Long.MAX_VALUE; - for(int segment = 0;segment<16;segment++){ - segmentLocks[segment].readLock().lock(); - try{ - long tail = engine.get(expireTails[segment],Serializer.LONG); - if(tail == 0) continue; - ExpireLinkNode ln = engine.get(tail, ExpireLinkNode.SERIALIZER); - if(ln==null || ln.time==0) continue; - ret = Math.min(ret, ln.time+expireTimeStart); - }finally{ - segmentLocks[segment].readLock().unlock(); - } - } - if(ret == Long.MAX_VALUE) ret =0; - return ret; - } - - protected static class ExpireRunnable implements Runnable{ - - //use weak referece to prevent memory leak - final WeakReference mapRef; - - public ExpireRunnable(HTreeMap map) { - this.mapRef = new WeakReference(map); - } - - @Override - public void run() { - if(CC.LOG_HTREEMAP && LOG.isLoggable(Level.FINE)){ - LOG.log(Level.FINE, "HTreeMap expirator thread started"); - } - boolean pause = false; - try { - while(true) { - - if (pause) { - Thread.sleep(1000); - } - - - HTreeMap map = mapRef.get(); - if (map == null || map.engine.isClosed() || map.shutdown) - return; - - //TODO what if store gets closed while working on this? - map.expirePurge(); - - if (map.engine.isClosed() || map.shutdown) - return; - - pause = ((!map.expireMaxSizeFlag || map.size() < map.expireMaxSize) - && (map.expireStoreSize == 0L || - Store.forEngine(map.engine).getCurrSize() - Store.forEngine(map.engine).getFreeSize() < map.expireStoreSize)); - - } - - }catch(Throwable e){ - LOG.log(Level.SEVERE, "HTreeMap expirator thread failed", e); - }finally { - HTreeMap m = mapRef.get(); - if (m != null) - m.expirationThreadNum.countDown(); - mapRef.clear(); - if(CC.LOG_HTREEMAP && LOG.isLoggable(Level.FINE)){ - LOG.log(Level.FINE, "HTreeMap expirator finished"); - } - } - } - - } - - - protected void expirePurge(){ - if(!expireFlag) return; - - long removePerSegment = 0; - if(expireMaxSizeFlag){ - long size = counter.get(); - if(size>expireMaxSize){ - removePerSegment=1+(size-expireMaxSize)/16; - if(LOG.isLoggable(Level.FINE)){ - LOG.log(Level.FINE, "HTreeMap expirator expireMaxSize, will remove {0,number,integer} entries per segment", - removePerSegment); - } - } - } - - - if(expireStoreSize!=0 && removePerSegment==0){ - Store store = Store.forEngine(engine); - long storeSize = store.getCurrSize()-store.getFreeSize(); - if(expireStoreSize>>28 == seg)) - throw new AssertionError(); - - final boolean remove = ++counter < removePerSegment || - ((expire!=0 || expireAccess!=0) && n.time+expireTimeStart ln = engine.get(n.keyRecid,LN_SERIALIZER); - removeInternal(ln.key,seg, n.hash, false); - }else{ - break; - } - last=n; - recid=n.next; - } - // patch linked list - if(last ==null ){ - //no items removed - }else if(recid == 0){ - //all items were taken, so zero items - engine.update(expireTails[seg],0L, Serializer.LONG); - engine.update(expireHeads[seg],0L, Serializer.LONG); - }else{ - //update tail to point to next item - engine.update(expireTails[seg],recid, Serializer.LONG); - //and update next item to point to tail - n = engine.get(recid, ExpireLinkNode.SERIALIZER); - n = n.copyPrev(0); - engine.update(recid,n,ExpireLinkNode.SERIALIZER); - } - return counter; -// expireCheckSegment(seg); - }finally{ - segmentLocks[seg].writeLock().unlock(); - } - } - - - protected void expireCheckSegment(int segment){ - long current = engine.get(expireTails[segment],Serializer.LONG); - if(current==0){ - if(engine.get(expireHeads[segment],Serializer.LONG)!=0) - throw new AssertionError("head not 0"); - return; - } - - long prev = 0; - while(current!=0){ - ExpireLinkNode curr = engine.get(current,ExpireLinkNode.SERIALIZER); - if(CC.PARANOID && ! (curr.prev==prev)) - throw new AssertionError("wrong prev "+curr.prev +" - "+prev); - prev= current; - current = curr.next; - } - if(engine.get(expireHeads[segment],Serializer.LONG)!=prev) - throw new AssertionError("wrong head"); - - } - - /** - * Make readonly snapshot view of current Map. Snapshot is immutable and not affected by modifications made by other threads. - * Useful if you need consistent view on Map. - *

- * Maintaining snapshot have some overhead, underlying Engine is closed after Map view is GCed. - * Please make sure to release reference to this Map view, so snapshot view can be garbage collected. - * - * @return snapshot - */ - public Map snapshot(){ - Engine snapshot = TxEngine.createSnapshotFor(engine); - return new HTreeMap(snapshot, counter==null?0:counter.recid, - hashSalt, segmentRecids, keySerializer, valueSerializer, - 0L,0L,0L,0L,0L, - null,null, null, null, false, null); - } - - - protected final Object modListenersLock = new Object(); - protected Bind.MapListener[] modListeners = new Bind.MapListener[0]; - - @Override - public void modificationListenerAdd(Bind.MapListener listener) { - synchronized (modListenersLock){ - Bind.MapListener[] modListeners2 = - Arrays.copyOf(modListeners,modListeners.length+1); - modListeners2[modListeners2.length-1] = listener; - modListeners = modListeners2; - } - - } - - @Override - public void modificationListenerRemove(Bind.MapListener listener) { - synchronized (modListenersLock){ - for(int i=0;i>>28].isWriteLockedByCurrentThread())) - throw new AssertionError(); - Bind.MapListener[] modListeners2 = modListeners; - for(Bind.MapListener listener:modListeners2){ - if(listener!=null) - listener.update(key, oldValue, newValue); - } - } - - /** - * Release resources and shutdown background tasks - */ - public void close(){ - shutdown = true; - try { - if(expirationThreadNum!=null) - expirationThreadNum.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - public Engine getEngine(){ - return engine; - } - -} diff --git a/src/main/java/org/mapdb/Hasher.java b/src/main/java/org/mapdb/Hasher.java deleted file mode 100644 index 3baae5d0f..000000000 --- a/src/main/java/org/mapdb/Hasher.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.util.Arrays; - -/** - * Calculates hash from an object. It also provides `equals` method. - * Provides an alternative hashing method for {@link org.mapdb.HTreeMap} - * - * @author Jan Kotek - */ -public interface Hasher { - - int hashCode(K k); - - boolean equals(K k1, K k2); - - - Hasher BASIC = new Hasher() { - @Override - public final int hashCode( Object k) { - return k.hashCode(); - } - - @Override - public boolean equals(Object k1, Object k2) { - return k1.equals(k2); - } - }; - - Hasher BYTE_ARRAY = new Hasher() { - @Override - public final int hashCode( byte[] k) { - return Arrays.hashCode(k); - } - - @Override - public boolean equals(byte[] k1, byte[] k2) { - return Arrays.equals(k1,k2); - } - }; - - Hasher CHAR_ARRAY = new Hasher() { - @Override - public final int hashCode( char[] k) { - return Arrays.hashCode(k); - } - - @Override - public boolean equals(char[] k1, char[] k2) { - return Arrays.equals(k1,k2); - } - }; - - Hasher INT_ARRAY = new Hasher() { - @Override - public final int hashCode( int[] k) { - return Arrays.hashCode(k); - } - - @Override - public boolean equals(int[] k1, int[] k2) { - return Arrays.equals(k1,k2); - } - }; - - Hasher LONG_ARRAY = new Hasher() { - @Override - public final int hashCode( long[] k) { - return Arrays.hashCode(k); - } - - @Override - public boolean equals(long[] k1, long[] k2) { - return Arrays.equals(k1,k2); - } - }; - - Hasher DOUBLE_ARRAY = new Hasher() { - @Override - public final int hashCode( double[] k) { - return Arrays.hashCode(k); - } - - @Override - public boolean equals(double[] k1, double[] k2) { - return Arrays.equals(k1,k2); - } - }; - - - Hasher ARRAY = new Hasher() { - @Override - public final int hashCode( Object[] k) { - return Arrays.hashCode(k); - } - - @Override - public boolean equals(Object[] k1, Object[] k2) { - return Arrays.equals(k1,k2); - } - }; - - -} \ No newline at end of file diff --git a/src/main/java/org/mapdb/LongConcurrentLRUMap.java b/src/main/java/org/mapdb/LongConcurrentLRUMap.java deleted file mode 100644 index 29046860c..000000000 --- a/src/main/java/org/mapdb/LongConcurrentLRUMap.java +++ /dev/null @@ -1,730 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 - * - * http://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. - */ - -package org.mapdb; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; - -/** - * A LRU cache implementation based upon ConcurrentHashMap and other techniques to reduce - * contention and synchronization overhead to utilize multiple CPU cores more effectively. - *

- * Note that the implementation does not follow a true LRU (least-recently-used) eviction - * strategy. Instead it strives to remove least recently used items but when the initial - * cleanup does not remove enough items to reach the 'acceptableWaterMark' limit, it can - * remove more items forcefully regardless of access order. - * - * MapDB note: reworked to implement LongMap. Original comes from: - * https://svn.apache.org/repos/asf/lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java - */ -public class LongConcurrentLRUMap extends LongMap { - - protected final LongConcurrentHashMap> map; - protected final int upperWaterMark, lowerWaterMark; - protected final ReentrantLock markAndSweepLock = new ReentrantLock(true); - protected boolean isCleaning = false; // not volatile... piggybacked on other volatile vars - - protected final int acceptableWaterMark; - protected long oldestEntry = 0; // not volatile, only accessed in the cleaning method - - - protected final AtomicLong accessCounter = new AtomicLong(0), - putCounter = new AtomicLong(0), - missCounter = new AtomicLong(), - evictionCounter = new AtomicLong(); - protected final AtomicInteger size = new AtomicInteger(); - - - - public LongConcurrentLRUMap(int upperWaterMark, final int lowerWaterMark, int acceptableWatermark, - int initialSize) { - if (upperWaterMark < 1) throw new IllegalArgumentException("upperWaterMark must be > 0"); - if (lowerWaterMark >= upperWaterMark) - throw new IllegalArgumentException("lowerWaterMark must be < upperWaterMark"); - map = new LongConcurrentHashMap>(initialSize); - this.upperWaterMark = upperWaterMark; - this.lowerWaterMark = lowerWaterMark; - this.acceptableWaterMark = acceptableWatermark; - } - - public LongConcurrentLRUMap(int size, int lowerWatermark) { - this(size, lowerWatermark, (int) Math.floor((lowerWatermark + size) / 2), - (int) Math.ceil(0.75 * size)); - } - - public V get(long key) { - CacheEntry e = map.get(key); - if (e == null) { - missCounter.incrementAndGet(); - return null; - } - e.lastAccessed = accessCounter.incrementAndGet(); - return e.value; - } - - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - public V remove(long key) { - CacheEntry cacheEntry = map.remove(key); - if (cacheEntry != null) { - size.decrementAndGet(); - return cacheEntry.value; - } - return null; - } - - public V put(long key, V val) { - if (val == null) return null; - CacheEntry e = new CacheEntry(key, val, accessCounter.incrementAndGet()); - CacheEntry oldCacheEntry = map.put(key, e); - int currentSize; - if (oldCacheEntry == null) { - currentSize = size.incrementAndGet(); - } else { - currentSize = size.get(); - } - - putCounter.incrementAndGet(); - - // Check if we need to clear out old entries from the cache. - // isCleaning variable is checked instead of markAndSweepLock.isLocked() - // for performance because every put invokation will check until - // the size is back to an acceptable level. - // - // There is a race between the check and the call to markAndSweep, but - // it's unimportant because markAndSweep actually aquires the lock or returns if it can't. - // - // Thread safety note: isCleaning read is piggybacked (comes after) other volatile reads - // in this method. - if (currentSize > upperWaterMark && !isCleaning) { - markAndSweep(); - } - return oldCacheEntry == null ? null : oldCacheEntry.value; - } - - /** - * Removes items from the cache to bring the size down - * to an acceptable value ('acceptableWaterMark'). - *

- * It is done in two stages. In the first stage, least recently used items are evicted. - * If, after the first stage, the cache size is still greater than 'acceptableSize' - * config parameter, the second stage takes over. - *

- * The second stage is more intensive and tries to bring down the cache size - * to the 'lowerWaterMark' config parameter. - */ - private void markAndSweep() { - // if we want to keep at least 1000 entries, then timestamps of - // current through current-1000 are guaranteed not to be the oldest (but that does - // not mean there are 1000 entries in that group... it's acutally anywhere between - // 1 and 1000). - // Also, if we want to remove 500 entries, then - // oldestEntry through oldestEntry+500 are guaranteed to be - // removed (however many there are there). - - if (!markAndSweepLock.tryLock()) return; - try { - long oldestEntry = this.oldestEntry; - isCleaning = true; - this.oldestEntry = oldestEntry; // volatile write to make isCleaning visible - - long timeCurrent = accessCounter.get(); - int sz = size.get(); - - int numRemoved = 0; - int numKept = 0; - long newestEntry = timeCurrent; - long newNewestEntry = -1; - long newOldestEntry = Long.MAX_VALUE; - - int wantToKeep = lowerWaterMark; - int wantToRemove = sz - lowerWaterMark; - - CacheEntry[] eset = new CacheEntry[sz]; - int eSize = 0; - - // System.out.println("newestEntry="+newestEntry + " oldestEntry="+oldestEntry); - // System.out.println("items removed:" + numRemoved + " numKept=" + numKept + " esetSz="+ eSize + " sz-numRemoved=" + (sz-numRemoved)); - - for (Iterator> iter = map.valuesIterator(); iter.hasNext();) { - CacheEntry ce = iter.next(); - // set lastAccessedCopy to avoid more volatile reads - ce.lastAccessedCopy = ce.lastAccessed; - long thisEntry = ce.lastAccessedCopy; - - // since the wantToKeep group is likely to be bigger than wantToRemove, check it first - if (thisEntry > newestEntry - wantToKeep) { - // this entry is guaranteed not to be in the bottom - // group, so do nothing. - numKept++; - newOldestEntry = Math.min(thisEntry, newOldestEntry); - } else if (thisEntry < oldestEntry + wantToRemove) { // entry in bottom group? - // this entry is guaranteed to be in the bottom group - // so immediately remove it from the map. - evictEntry(ce.key); - numRemoved++; - } else { - // This entry *could* be in the bottom group. - // Collect these entries to avoid another full pass... this is wasted - // effort if enough entries are normally removed in this first pass. - // An alternate impl could make a full second pass. - if (eSize < eset.length-1) { - eset[eSize++] = ce; - newNewestEntry = Math.max(thisEntry, newNewestEntry); - newOldestEntry = Math.min(thisEntry, newOldestEntry); - } - } - } - - // System.out.println("items removed:" + numRemoved + " numKept=" + numKept + " esetSz="+ eSize + " sz-numRemoved=" + (sz-numRemoved)); - - int numPasses=1; // maximum number of linear passes over the data - - // if we didn't remove enough entries, then make more passes - // over the values we collected, with updated min and max values. - while (sz - numRemoved > acceptableWaterMark && --numPasses>=0) { - - oldestEntry = newOldestEntry == Long.MAX_VALUE ? oldestEntry : newOldestEntry; - newOldestEntry = Long.MAX_VALUE; - newestEntry = newNewestEntry; - newNewestEntry = -1; - wantToKeep = lowerWaterMark - numKept; - wantToRemove = sz - lowerWaterMark - numRemoved; - - // iterate backward to make it easy to remove items. - for (int i=eSize-1; i>=0; i--) { - CacheEntry ce = eset[i]; - long thisEntry = ce.lastAccessedCopy; - - if (thisEntry > newestEntry - wantToKeep) { - // this entry is guaranteed not to be in the bottom - // group, so do nothing but remove it from the eset. - numKept++; - // remove the entry by moving the last element to it's position - eset[i] = eset[eSize-1]; - eSize--; - - newOldestEntry = Math.min(thisEntry, newOldestEntry); - - } else if (thisEntry < oldestEntry + wantToRemove) { // entry in bottom group? - - // this entry is guaranteed to be in the bottom group - // so immediately remove it from the map. - evictEntry(ce.key); - numRemoved++; - - // remove the entry by moving the last element to it's position - eset[i] = eset[eSize-1]; - eSize--; - } else { - // This entry *could* be in the bottom group, so keep it in the eset, - // and update the stats. - newNewestEntry = Math.max(thisEntry, newNewestEntry); - newOldestEntry = Math.min(thisEntry, newOldestEntry); - } - } - // System.out.println("items removed:" + numRemoved + " numKept=" + numKept + " esetSz="+ eSize + " sz-numRemoved=" + (sz-numRemoved)); - } - - - - // if we still didn't remove enough entries, then make another pass while - // inserting into a priority queue - if (sz - numRemoved > acceptableWaterMark) { - - oldestEntry = newOldestEntry == Long.MAX_VALUE ? oldestEntry : newOldestEntry; - newOldestEntry = Long.MAX_VALUE; - newestEntry = newNewestEntry; - newNewestEntry = -1; - wantToKeep = lowerWaterMark - numKept; - wantToRemove = sz - lowerWaterMark - numRemoved; - - PQueue queue = new PQueue(wantToRemove); - - for (int i=eSize-1; i>=0; i--) { - CacheEntry ce = eset[i]; - long thisEntry = ce.lastAccessedCopy; - - if (thisEntry > newestEntry - wantToKeep) { - // this entry is guaranteed not to be in the bottom - // group, so do nothing but remove it from the eset. - numKept++; - // removal not necessary on last pass. - // eset[i] = eset[eSize-1]; - // eSize--; - - newOldestEntry = Math.min(thisEntry, newOldestEntry); - - } else if (thisEntry < oldestEntry + wantToRemove) { // entry in bottom group? - // this entry is guaranteed to be in the bottom group - // so immediately remove it. - evictEntry(ce.key); - numRemoved++; - - // removal not necessary on last pass. - // eset[i] = eset[eSize-1]; - // eSize--; - } else { - // This entry *could* be in the bottom group. - // add it to the priority queue - - // everything in the priority queue will be removed, so keep track of - // the lowest value that ever comes back out of the queue. - - // first reduce the size of the priority queue to account for - // the number of items we have already removed while executing - // this loop so far. - queue.myMaxSize = sz - lowerWaterMark - numRemoved; - while (queue.size() > queue.myMaxSize && queue.size() > 0) { - CacheEntry otherEntry = queue.pop(); - newOldestEntry = Math.min(otherEntry.lastAccessedCopy, newOldestEntry); - } - if (queue.myMaxSize <= 0) break; - - Object o = queue.myInsertWithOverflow(ce); - if (o != null) { - newOldestEntry = Math.min(((CacheEntry)o).lastAccessedCopy, newOldestEntry); - } - } - } - - // Now delete everything in the priority queue. - // avoid using pop() since order doesn't matter anymore - for (CacheEntry ce : queue.getValues()) { - if (ce==null) continue; - evictEntry(ce.key); - numRemoved++; - } - - // System.out.println("items removed:" + numRemoved + " numKept=" + numKept + " initialQueueSize="+ wantToRemove + " finalQueueSize=" + queue.size() + " sz-numRemoved=" + (sz-numRemoved)); - } - - oldestEntry = newOldestEntry == Long.MAX_VALUE ? oldestEntry : newOldestEntry; - this.oldestEntry = oldestEntry; - } finally { - isCleaning = false; // set before markAndSweep.unlock() for visibility - markAndSweepLock.unlock(); - } - } - - private static class PQueue extends PriorityQueue> { - int myMaxSize; - final Object[] heap; - - PQueue(int maxSz) { - super(maxSz); - heap = getHeapArray(); - myMaxSize = maxSz; - } - - - Iterable> getValues() { - return (Collection)Collections.unmodifiableCollection(Arrays.asList(heap)); - } - - @Override - protected boolean lessThan(CacheEntry a, CacheEntry b) { - // reverse the parameter order so that the queue keeps the oldest items - return b.lastAccessedCopy < a.lastAccessedCopy; - } - - // necessary because maxSize is private in base class - public CacheEntry myInsertWithOverflow(CacheEntry element) { - if (size() < myMaxSize) { - add(element); - return null; - } else if (size() > 0 && !lessThan(element, (CacheEntry) heap[1])) { - CacheEntry ret = (CacheEntry) heap[1]; - heap[1] = element; - updateTop(); - return ret; - } else { - return element; - } - } - } - - /** A PriorityQueue maintains a partial ordering of its elements such that the - * least element can always be found in constant time. Put()'s and pop()'s - * require log(size) time. - * - *

NOTE: This class will pre-allocate a full array of - * length maxSize+1 if instantiated via the - * {@link #PriorityQueue(int,boolean)} constructor with - * prepopulate set to true. - * - * @lucene.internal - */ - private static abstract class PriorityQueue { - private int size; - private final int maxSize; - private final T[] heap; - - public PriorityQueue(int maxSize) { - this(maxSize, true); - } - - public PriorityQueue(int maxSize, boolean prepopulate) { - size = 0; - int heapSize; - if (0 == maxSize) - // We allocate 1 extra to avoid if statement in top() - heapSize = 2; - else { - if (maxSize == Integer.MAX_VALUE) { - // Don't wrap heapSize to -1, in this case, which - // causes a confusing NegativeArraySizeException. - // Note that very likely this will simply then hit - // an OOME, but at least that's more indicative to - // caller that this values is too big. We don't +1 - // in this case, but it's very unlikely in practice - // one will actually insert this many objects into - // the PQ: - heapSize = Integer.MAX_VALUE; - } else { - // NOTE: we add +1 because all access to heap is - // 1-based not 0-based. heap[0] is unused. - heapSize = maxSize + 1; - } - } - heap = (T[]) new Object[heapSize]; // T is unbounded type, so this unchecked cast works always - this.maxSize = maxSize; - - if (prepopulate) { - // If sentinel objects are supported, populate the queue with them - T sentinel = getSentinelObject(); - if (sentinel != null) { - heap[1] = sentinel; - for (int i = 2; i < heap.length; i++) { - heap[i] = getSentinelObject(); - } - size = maxSize; - } - } - } - - /** Determines the ordering of objects in this priority queue. Subclasses - * must define this one method. - * @return true iff parameter a is less than parameter b. - */ - protected abstract boolean lessThan(T a, T b); - - /** - * This method can be overridden by extending classes to return a sentinel - * object which will be used by the {@link PriorityQueue#PriorityQueue(int,boolean)} - * constructor to fill the queue, so that the code which uses that queue can always - * assume it's full and only change the top without attempting to insert any new - * object.
- * - * Those sentinel values should always compare worse than any non-sentinel - * value (i.e., {@link #lessThan} should always favor the - * non-sentinel values).
- * - * By default, this method returns false, which means the queue will not be - * filled with sentinel values. Otherwise, the value returned will be used to - * pre-populate the queue. Adds sentinel values to the queue.
- * - * If this method is extended to return a non-null value, then the following - * usage pattern is recommended: - * - *

-         * // extends getSentinelObject() to return a non-null value.
-         * PriorityQueue<MyObject> pq = new MyQueue<MyObject>(numHits);
-         * // save the 'top' element, which is guaranteed to not be null.
-         * MyObject pqTop = pq.top();
-         * <...>
-         * // now in order to add a new element, which is 'better' than top (after
-         * // you've verified it is better), it is as simple as:
-         * pqTop.change().
-         * pqTop = pq.updateTop();
-         * 
- * - * NOTE: if this method returns a non-null value, it will be called by - * the {@link PriorityQueue#PriorityQueue(int,boolean)} constructor - * {@link #size()} times, relying on a new object to be returned and will not - * check if it's null again. Therefore you should ensure any call to this - * method creates a new instance and behaves consistently, e.g., it cannot - * return null if it previously returned non-null. - * - * @return the sentinel object to use to pre-populate the queue, or null if - * sentinel objects are not supported. - */ - protected T getSentinelObject() { - return null; - } - - /** - * Adds an Object to a PriorityQueue in log(size) time. If one tries to add - * more objects than maxSize from initialize an - * {@link ArrayIndexOutOfBoundsException} is thrown. - * - * @return the new 'top' element in the queue. - */ - public final T add(T element) { - size++; - heap[size] = element; - upHeap(); - return heap[1]; - } - - /** - * Adds an Object to a PriorityQueue in log(size) time. - * It returns the object (if any) that was - * dropped off the heap because it was full. This can be - * the given parameter (in case it is smaller than the - * full heap's minimum, and couldn't be added), or another - * object that was previously the smallest value in the - * heap and now has been replaced by a larger one, or null - * if the queue wasn't yet full with maxSize elements. - */ - public T insertWithOverflow(T element) { - if (size < maxSize) { - add(element); - return null; - } else if (size > 0 && !lessThan(element, heap[1])) { - T ret = heap[1]; - heap[1] = element; - updateTop(); - return ret; - } else { - return element; - } - } - - /** Returns the least element of the PriorityQueue in constant time. */ - public final T top() { - // We don't need to check size here: if maxSize is 0, - // then heap is length 2 array with both entries null. - // If size is 0 then heap[1] is already null. - return heap[1]; - } - - /** Removes and returns the least element of the PriorityQueue in log(size) - time. */ - public final T pop() { - if (size > 0) { - T result = heap[1]; // save first value - heap[1] = heap[size]; // move last to first - heap[size] = null; // permit GC of objects - size--; - downHeap(); // adjust heap - return result; - } else - return null; - } - - /** - * Should be called when the Object at top changes values. Still log(n) worst - * case, but it's at least twice as fast to - * - *
-         * pq.top().change();
-         * pq.updateTop();
-         * 
- * - * instead of - * - *
-         * o = pq.pop();
-         * o.change();
-         * pq.push(o);
-         * 
- * - * @return the new 'top' element. - */ - public final T updateTop() { - downHeap(); - return heap[1]; - } - - /** Returns the number of elements currently stored in the PriorityQueue. */ - public final int size() { - return size; - } - - /** Removes all entries from the PriorityQueue. */ - public final void clear() { - for (int i = 0; i <= size; i++) { - heap[i] = null; - } - size = 0; - } - - private void upHeap() { - int i = size; - T node = heap[i]; // save bottom node - int j = i >>> 1; - while (j > 0 && lessThan(node, heap[j])) { - heap[i] = heap[j]; // shift parents down - i = j; - j = j >>> 1; - } - heap[i] = node; // install saved node - } - - private void downHeap() { - int i = 1; - T node = heap[i]; // save top node - int j = i << 1; // find smaller child - int k = j + 1; - if (k <= size && lessThan(heap[k], heap[j])) { - j = k; - } - while (j <= size && lessThan(heap[j], node)) { - heap[i] = heap[j]; // shift up child - i = j; - j = i << 1; - k = j + 1; - if (k <= size && lessThan(heap[k], heap[j])) { - j = k; - } - } - heap[i] = node; // install saved node - } - - /** This method returns the internal heap array as Object[]. - * @lucene.internal - */ - protected final T[] getHeapArray() { - return heap; - } - } - - - private void evictEntry(long key) { - CacheEntry o = map.remove(key); - if (o == null) return; - size.decrementAndGet(); - evictionCounter.incrementAndGet(); - evictedEntry(o.key,o.value); - } - - - public int size() { - return size.get(); - } - - @Override - public Iterator valuesIterator() { - final Iterator> iter = map.valuesIterator(); - return new Iterator(){ - - @Override - public boolean hasNext() { - return iter.hasNext(); - } - - @Override - public V next() { - return iter.next().value; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public LongMapIterator longMapIterator() { - final LongMapIterator> iter = map.longMapIterator(); - return new LongMapIterator() { - @Override - public boolean moveToNext() { - return iter.moveToNext(); - } - - @Override - public long key() { - return iter.key(); - } - - @Override - public V value() { - return iter.value().value; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - public void clear() { - map.clear(); - } - - public LongMap> getMap() { - return map; - } - - private static final class CacheEntry implements Comparable> { - final long key; - final V value; - volatile long lastAccessed = 0; - long lastAccessedCopy = 0; - - - public CacheEntry(long key, V value, long lastAccessed) { - this.key = key; - this.value = value; - this.lastAccessed = lastAccessed; - } - - @Override - public int compareTo(CacheEntry that) { - if (this.lastAccessedCopy == that.lastAccessedCopy) return 0; - return this.lastAccessedCopy < that.lastAccessedCopy ? 1 : -1; - } - - @Override - public int hashCode() { - return value.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return value.equals(obj); - } - - @Override - public String toString() { - return "key: " + key + " value: " + value + " lastAccessed:" + lastAccessed; - } - } - - - - - - - /** override this method to get notified about evicted entries*/ - protected void evictedEntry(long key, V value){ - - } -} diff --git a/src/main/java/org/mapdb/Pump.java b/src/main/java/org/mapdb/Pump.java deleted file mode 100644 index e19c89e36..000000000 --- a/src/main/java/org/mapdb/Pump.java +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ -package org.mapdb; - -import java.io.*; -import java.nio.ByteBuffer; -import java.util.*; - -/** - * Data Pump moves data from one source to other. - * It can be used to import data from text file, or copy store from memory to disk. - */ -public final class Pump { - - /** copies all data from first DB to second DB */ - //TODO Pump between stores is disabled for now, make this method public once enabled - static void copy(DB db1, DB db2){ - copy(Store.forDB(db1), Store.forDB(db2)); - db2.engine.clearCache(); - db2.reinit(); - } - - /** copies all data from first store to second store */ - //TODO Pump between stores is disabled for now, make this method public once enabled - static void copy(Store s1, Store s2){ - long maxRecid =s1.getMaxRecid(); - for(long recid=1;recid<=maxRecid;recid++){ - ByteBuffer bb = s1.getRaw(recid); - //System.out.println(recid+" - "+(bb==null?0:bb.remaining())); - if(bb==null) continue; - s2.updateRaw(recid, bb); - } - - //now release unused recids - for(Iterator iter = s1.getFreeRecids(); iter.hasNext();){ - s2.delete(iter.next(), null); - } - } - - - - /** - * Sorts large data set by given `Comparator`. Data are sorted with in-memory cache and temporary files. - * - * @param source iterator over unsorted data - * @param mergeDuplicates should be duplicate keys merged into single one? - * @param batchSize how much items can fit into heap memory - * @param comparator used to sort data - * @param serializer used to store data in temporary files - * @return iterator over sorted data set - */ - public static Iterator sort(Iterator source, boolean mergeDuplicates, final int batchSize, - Comparator comparator, final Serializer serializer){ - if(batchSize<=0) throw new IllegalArgumentException(); - if(comparator==null) - comparator=Fun.COMPARATOR; - if(source==null) - source = Fun.EMPTY_ITERATOR; - - int counter = 0; - final Object[] presort = new Object[batchSize]; - final List presortFiles = new ArrayList(); - final List presortCount2 = new ArrayList(); - - try{ - while(source.hasNext()){ - presort[counter]=source.next(); - counter++; - - if(counter>=batchSize){ - //sort all items - Arrays.sort(presort,comparator); - - //flush presort into temporary file - File f = File.createTempFile("mapdb","sort"); - f.deleteOnExit(); - presortFiles.add(f); - DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(f))); - for(Object e:presort){ - serializer.serialize(out,e); - } - out.close(); - presortCount2.add(counter); - Arrays.fill(presort,0); - counter = 0; - } - } - //now all records from source are fetch - if(presortFiles.isEmpty()){ - //no presort files were created, so on-heap sorting is enough - Arrays.sort(presort,0,counter,comparator); - return arrayIterator(presort,0, counter); - } - - final int[] presortCount = new int[presortFiles.size()]; - for(int i=0;i0; - } - - @Override public Object next() { - try { - Object ret = serializer.deserialize(ins[pos],-1); - if(--presortCount[pos]==0){ - ins[pos].close(); - presortFiles.get(pos).delete(); - } - return ret; - } catch (IOException e) { - throw new IOError(e); - } - } - - @Override public void remove() { - //ignored - } - - }; - } - - //and add iterator over data on-heap - Arrays.sort(presort,0,counter,comparator); - iterators[iterators.length-1] = arrayIterator(presort,0,counter); - - //and finally sort presorted iterators and return iterators over them - return sort(comparator, mergeDuplicates, iterators); - - }catch(IOException e){ - throw new IOError(e); - }finally{ - for(File f:presortFiles) f.delete(); - } - } - - - - - /** - * Merge presorted iterators into single sorted iterator. - * - * @param comparator used to compare data - * @param mergeDuplicates if duplicate keys should be merged into single one - * @param iterators array of already sorted iterators - * @return sorted iterator - */ - public static Iterator sort(Comparator comparator, final boolean mergeDuplicates, final Iterator... iterators) { - final Comparator comparator2 = comparator==null?Fun.COMPARATOR:comparator; - return new Iterator(){ - - final NavigableSet items = new TreeSet( - new Fun.ArrayComparator(new Comparator[]{comparator2,Fun.COMPARATOR})); - - Object next = this; //is initialized with this so first `next()` will not throw NoSuchElementException - - { - for(int i=0;i0){ - throw new IllegalArgumentException("One of the iterators is not sorted"); - } - - Iterator iter = iterators[(Integer)lo[1]]; - if(iter.hasNext()){ - items.add(new Object[]{iter.next(),lo[1]}); - } - - if(mergeDuplicates){ - while(true){ - Iterator subset = Fun.filter(items,next).iterator(); - if(!subset.hasNext()) - break; - List toadd = new ArrayList(); - while(subset.hasNext()){ - Object[] t = subset.next(); - items.remove(t); - iter = iterators[(Integer)t[1]]; - if(iter.hasNext()) - toadd.add(new Object[]{iter.next(),t[1]}); - } - items.addAll(toadd); - } - } - - - return (E) oldNext; - } - - @Override public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - - /** - * Merges multiple iterators into single iterator. - * Result iterator will return entries from all iterators. - * It does not do sorting or any other special functionality. - * Does not allow null elements. - * - * @param iters - iterators to be merged - * @return union of all iterators. - */ - public static Iterator merge(final Iterator... iters){ - if(iters.length==0) - return Fun.EMPTY_ITERATOR; - - return new Iterator() { - - int i = 0; - Object next = this; - { - next(); - } - - @Override public boolean hasNext() { - return next!=null; - } - - @Override public E next() { - if(next==null) - throw new NoSuchElementException(); - - //move to next iterator if necessary - while(!iters[i].hasNext()){ - i++; - if(i==iters.length){ - //reached end of iterators - Object ret = next; - next = null; - return (E) ret; - } - } - - //take next item from iterator - Object ret = next; - next = iters[i].next(); - return (E) ret; - } - - @Override public void remove() { - throw new UnsupportedOperationException(); - } - }; - - } - - /** - * Build BTreeMap (or TreeSet) from presorted data. - * This method is much faster than usual import using `Map.put(key,value)` method. - * It is because tree integrity does not have to be maintained and - * tree can be created in linear way with. - * - * This method expect data to be presorted in **reverse order** (highest to lowest). - * There are technical reason for this requirement. - * To sort unordered data use {@link Pump#sort(java.util.Iterator, boolean, int, java.util.Comparator, Serializer)} - * - * This method does not call commit. You should disable Write Ahead Log when this method is used {@link org.mapdb.DBMaker#transactionDisable()} - * - * - * @param source iterator over source data, must be reverse sorted - * @param keyExtractor transforms items from source iterator into keys. If null source items will be used directly as keys. - * @param valueExtractor transforms items from source iterator into values. If null BTreeMap will be constructed without values (as Set) - * @param ignoreDuplicates should be duplicate keys merged into single one? - * @param nodeSize maximal BTree node size before it is splited. - * @param valuesStoredOutsideNodes if true values will not be stored as part of BTree nodes - * @param counterRecid TODO make size counter friendly to use - * @param keySerializer serializer for keys, use null for default value - * @param valueSerializer serializer for value, use null for default value - * @throws IllegalArgumentException if source iterator is not reverse sorted - */ - public static long buildTreeMap(Iterator source, - Engine engine, - Fun.Function1 keyExtractor, - Fun.Function1 valueExtractor, - boolean ignoreDuplicates, - int nodeSize, - boolean valuesStoredOutsideNodes, - long counterRecid, - BTreeKeySerializer keySerializer, - Serializer valueSerializer) - { - - - final double NODE_LOAD = 0.75; - - Serializer nodeSerializer = new BTreeMap.NodeSerializer(valuesStoredOutsideNodes,keySerializer,valueSerializer,0); - - - final int nload = (int) (nodeSize * NODE_LOAD); - ArrayList> dirKeys = arrayList(arrayList(null)); - ArrayList> dirRecids = arrayList(arrayList(0L)); - - long counter = 0; - - long nextNode = 0; - - //fill node with data - List keys = arrayList(null); - ArrayList values = new ArrayList(); - //traverse iterator - K oldKey = null; - while(source.hasNext()){ - - nodeLoop:for(int i=0;i=0) - throw new IllegalArgumentException("Keys in 'source' iterator are not reverse sorted"); - oldKey = key; - keys.add(key); - counter++; - - Object val = valueExtractor!=null?valueExtractor.run(next):BTreeMap.EMPTY; - if(val==null) throw new NullPointerException("extractValue returned null value"); - if(valuesStoredOutsideNodes){ - long recid = engine.put((V) val,valueSerializer); - val = new BTreeMap.ValRef(recid); - } - values.add(val); - - } - //insert node - if(!source.hasNext()){ - keys.add(null); - values.add(null); - } - - Collections.reverse(keys); - - Object nextVal = values.remove(values.size()-1); - Collections.reverse(values); - - - - boolean rightEdge = keys.get(keys.size()-1)==null; - if(rightEdge) - keys.remove(keys.size()-1); - boolean leftEdge = keys.get(0)==null; - if(leftEdge) - keys.remove(0); - BTreeMap.LeafNode node = new BTreeMap.LeafNode( - keySerializer.arrayToKeys(keys.toArray()), - leftEdge,rightEdge, false, - values.toArray() , nextNode); - nextNode = engine.put(node,nodeSerializer); - K nextKey = keys.get(0); - keys.clear(); - - keys.add(nextKey); - keys.add(nextKey); - - values.clear(); - values.add(nextVal); - - dirKeys.get(0).add(node.key(keySerializer,0)); - dirRecids.get(0).add(nextNode); - - //check node sizes and split them if needed - for(int i=0;i keys2 = dirKeys.get(i); - Collections.reverse(keys2); - Collections.reverse(dirRecids.get(i)); - - if(keys2.size()>2 && keys2.get(0)==null && keys2.get(1)==null){ - keys2.remove(0); - dirRecids.get(i).remove(0); - } - - //put node into store - boolean rightEdge3 = keys2.get(keys2.size()-1)==null; - if(rightEdge3){ - keys2.remove(keys2.size()-1); - } - boolean leftEdge3 = keys2.get(0)==null; - if(leftEdge3){ - keys2.remove(0); - } - BTreeMap.DirNode dir = new BTreeMap.DirNode( - keySerializer.arrayToKeys(keys2.toArray()), - leftEdge3,rightEdge3, false, - toLongArray(dirRecids.get(i))); - long dirRecid = engine.put(dir,nodeSerializer); - Object dirStart = keys2.get(0); - dirKeys.get(i+1).add(dirStart); - dirRecids.get(i+1).add(dirRecid); - - } - - //and finally write root - final int len = dirKeys.size()-1; - Collections.reverse(dirKeys.get(len)); - Collections.reverse(dirRecids.get(len)); - - //and do counter - if(counterRecid!=0) - engine.update(counterRecid, counter, Serializer.LONG); - - - boolean rightEdge4 = dirKeys.get(len).get(dirKeys.get(len).size()-1)==null; - if(rightEdge4){ - dirKeys.get(len).remove(dirKeys.get(len).size()-1); - } - boolean leftEdge4 = dirKeys.get(len).get(0)==null; - if(leftEdge4){ - dirKeys.get(len).remove(0); - } - BTreeMap.DirNode dir = new BTreeMap.DirNode( - keySerializer.arrayToKeys(dirKeys.get(len).toArray()), - leftEdge4,rightEdge4, false, - toLongArray(dirRecids.get(len))); - long rootRecid = engine.put(dir, nodeSerializer); - return engine.put(rootRecid,Serializer.LONG); //root recid - } - - private static long[] toLongArray(List child) { - long[] ret= new long[child.size()]; - for(int i=0;i ArrayList arrayList(E item){ - ArrayList ret = new ArrayList(); - ret.add(item); - return ret; - } - - private static Iterator arrayIterator(final Object[] array, final int fromIndex, final int toIndex) { - return new Iterator(){ - - int index = fromIndex; - - @Override - public boolean hasNext() { - return index=toIndex) throw new NoSuchElementException(); - return (E) array[index++]; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - -} diff --git a/src/main/java/org/mapdb/Queues.java b/src/main/java/org/mapdb/Queues.java deleted file mode 100644 index d01924e73..000000000 --- a/src/main/java/org/mapdb/Queues.java +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ -package org.mapdb; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -/** - * Various queue algorithms - */ -public final class Queues { - - private Queues(){} - - - - public static abstract class SimpleQueue implements BlockingQueue { - - protected final boolean useLocks; - protected final ReentrantLock[] locks; - - - protected static final int TICK = 10*1000; - - protected final Engine engine; - protected final Serializer serializer; - - protected final Atomic.Long head; - - - protected static class NodeSerializer implements Serializer.Trusted> { - private final Serializer serializer; - - public NodeSerializer(Serializer serializer) { - this.serializer = serializer; - } - - @Override - public void serialize(DataOutput out, Node value) throws IOException { - if(value==Node.EMPTY) return; - DataIO.packLong(out,value.next); - serializer.serialize(out, value.value); - } - - @Override - public Node deserialize(DataInput in, int available) throws IOException { - if(available==0)return (Node) Node.EMPTY; - return new Node(DataIO.unpackLong(in), serializer.deserialize(in,-1)); - } - - @Override - public int fixedSize() { - return -1; - } - - } - - protected final Serializer> nodeSerializer; - - - public SimpleQueue(Engine engine, Serializer serializer, long headRecidRef, boolean useLocks) { - this.engine = engine; - this.serializer = serializer; - head = new Atomic.Long(engine,headRecidRef); - nodeSerializer = new NodeSerializer(serializer); - this.useLocks = useLocks; - if(useLocks){ - locks = new ReentrantLock[CC.CONCURRENCY]; - for(int i=0;i) Node.EMPTY,nodeSerializer); - } - return (E) n.value; - } - - }finally{ - if(useLocks)locks[Store.lockPos(head2)].unlock(); - } - } - } - - - protected static final class Node{ - - protected static final Node EMPTY = new Node(0L, null); - - final protected long next; - final protected E value; - - public Node(long next, E value) { - this.next = next; - this.value = value; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Node node = (Node) o; - - if (next != node.next) return false; - if (value != null ? !value.equals(node.value) : node.value != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = (int) (next ^ (next >>> 32)); - result = 31 * result + (value != null ? value.hashCode() : 0); - return result; - } - } - - @Override - public void clear() { - while(!isEmpty()) - poll(); - } - - - @Override - public E remove() { - E ret = poll(); - if(ret == null) throw new NoSuchElementException(); - return ret; - } - - - @Override - public E element() { - E ret = peek(); - if(ret == null) throw new NoSuchElementException(); - return ret; - } - - - @Override - public boolean offer(E e) { - try { - return add(e); - }catch (IllegalStateException ee){ - return false; - } - } - - - @Override - public void put(E e) throws InterruptedException { - while(!offer(e)){ - Thread.sleep(0,TICK); - } - } - - @Override - public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { - if(offer(e)) return true; - long target = System.currentTimeMillis() + unit.toMillis(timeout); - while(target>=System.currentTimeMillis()){ - if(offer(e)) - return true; - Thread.sleep(0,TICK); - } - - return false; - } - - @Override - public E take() throws InterruptedException { - E e = poll(); - while(e==null){ - Thread.sleep(0,TICK); - e = poll(); - } - return e; - } - - @Override - public E poll(long timeout, TimeUnit unit) throws InterruptedException { - E e = poll(); - if(e!=null) return e; - long target = System.currentTimeMillis() + unit.toMillis(timeout); - while(target>=System.currentTimeMillis()){ - Thread.sleep(0,TICK); - e = poll(); - if(e!=null) - return e; - } - return null; - } - - @Override - public int drainTo(Collection c) { - return drainTo(c,Integer.MAX_VALUE); - } - - @Override - public int drainTo(Collection c, int maxElements) { - int counter=0; - while(counter iterator() { - throw new UnsupportedOperationException(); - } - - @Override - public Object[] toArray() { - throw new UnsupportedOperationException(); - } - - @Override - public T[] toArray(T[] a) { - throw new UnsupportedOperationException(); - } - - - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException(); - } - } - - - - /** - * Last in first out lock-free queue - * - * @param - */ - public static class Stack extends SimpleQueue { - - - - public Stack(Engine engine, Serializer serializer, long headerRecidRef, boolean useLocks) { - super(engine, serializer, headerRecidRef, useLocks); - } - - @Override - public boolean add(E e) { - long head2 = head.get(); - Node n = new Node(head2, e); - long recid = engine.put(n, nodeSerializer); - while(!head.compareAndSet(head2, recid)){ - //failed to update head, so read new value and start over - head2 = head.get(); - n = new Node(head2, e); - engine.update(recid, n, nodeSerializer); - } - return true; - } - } - - - /** - * First in first out lock-free queue - * - * @param - */ - public static class Queue extends SimpleQueue { - - protected final Atomic.Long tail; - - public Queue(Engine engine, Serializer serializer, long headerRecid, - long nextTailRecid, boolean useLocks) { - super(engine, serializer,headerRecid,useLocks); - tail = new Atomic.Long(engine,nextTailRecid); - } - - @Override - public boolean add(E e) { - long nextTail = engine.put((Node) Node.EMPTY,nodeSerializer); - long tail2 = tail.get(); - while(!tail.compareAndSet(tail2,nextTail)){ - tail2 = tail.get(); - } - //now we have tail2 just for us - Node n = new Node(nextTail,e); - engine.update(tail2,n,nodeSerializer); - return true; - } - - - - } - - - - - public static class CircularQueue extends SimpleQueue { - - protected final Atomic.Long headInsert; - //TODO is there a way to implement this without global locks? - protected final Lock lock = new ReentrantLock(CC.FAIR_LOCKS); - protected final long size; - - public CircularQueue(Engine engine, Serializer serializer, long headRecid, long headInsertRecid, long size) { - super(engine, serializer, headRecid,false); - headInsert = new Atomic.Long(engine, headInsertRecid); - this.size = size; - } - - @Override - public boolean add(Object o) { - lock.lock(); - try{ - long nRecid = headInsert.get(); - Node n = engine.get(nRecid, nodeSerializer); - n = new Node(n.next, (E) o); - engine.update(nRecid, n, nodeSerializer); - headInsert.set(n.next); - //move 'poll' head if it points to currently replaced item - head.compareAndSet(nRecid, n.next); - return true; - }finally { - lock.unlock(); - } - } - - @Override - public void clear() { - // praise locking - lock.lock(); - try { - for (int i = 0; i < size; i++) { - poll(); - } - } finally { - lock.unlock(); - } - } - - @Override - public E poll() { - lock.lock(); - try{ - long nRecid = head.get(); - Node n = engine.get(nRecid, nodeSerializer); - engine.update(nRecid, new Node(n.next, null), nodeSerializer); - head.set(n.next); - return n.value; - }finally { - lock.unlock(); - } - } - - @Override - public E peek() { - lock.lock(); - try{ - long nRecid = head.get(); - Node n = engine.get(nRecid, nodeSerializer); - return n.value; - }finally { - lock.unlock(); - } - } - - } - - -} diff --git a/src/main/java/org/mapdb/Serializer.java b/src/main/java/org/mapdb/Serializer.java deleted file mode 100644 index 9c760f860..000000000 --- a/src/main/java/org/mapdb/Serializer.java +++ /dev/null @@ -1,849 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ -package org.mapdb; - - -import java.io.*; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.nio.charset.Charset; -import java.util.Date; -import java.util.UUID; - -/** - * Provides serialization and deserialization - * - * @author Jan Kotek - */ -public interface Serializer { - - - Serializer CHAR = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Character value) throws IOException { - out.writeChar(value.charValue()); - } - - @Override - public Character deserialize(DataInput in, int available) throws IOException { - return in.readChar(); - } - - @Override - public int fixedSize() { - return 2; - } - }; - - - /** - * Indicates that serializer can be trusted with data sizes. - * Should be only implemented by build-in serializers from MapDB - * - * TODO explain trusted serializers - * - * @param serialized type - */ - interface Trusted extends Serializer{ - - } - - /** - * Serializes strings using UTF8 encoding. - * Stores string size so can be used as collection serializer. - * Does not handle null values - */ - Serializer STRING = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, String value) throws IOException { - out.writeUTF(value); - } - - @Override - public String deserialize(DataInput in, int available) throws IOException { - return in.readUTF(); - } - - @Override - public int fixedSize() { - return -1; - } - }; - - /** - * Serializes strings using UTF8 encoding. - * Deserialized String is interned {@link String#intern()}, - * so it could save some memory. - * - * Stores string size so can be used as collection serializer. - * Does not handle null values - */ - Serializer STRING_INTERN = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, String value) throws IOException { - out.writeUTF(value); - } - - @Override - public String deserialize(DataInput in, int available) throws IOException { - return in.readUTF().intern(); - } - - @Override - public int fixedSize() { - return -1; - } - - }; - - /** - * Serializes strings using ASCII encoding (8 bit character). - * Is faster compared to UTF8 encoding. - * Stores string size so can be used as collection serializer. - * Does not handle null values - */ - Serializer STRING_ASCII = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, String value) throws IOException { - char[] cc = new char[value.length()]; - //TODO does this really works? is not char 2 byte unsigned? - value.getChars(0,cc.length,cc,0); - DataIO.packInt(out,cc.length); - for(char c:cc){ - out.write(c); - } - } - - @Override - public String deserialize(DataInput in, int available) throws IOException { - int size = DataIO.unpackInt(in); - char[] cc = new char[size]; - for(int i=0;i STRING_NOSIZE = new Serializer.Trusted() { - - private final Charset UTF8_CHARSET = Charset.forName("UTF8"); - - @Override - public void serialize(DataOutput out, String value) throws IOException { - final byte[] bytes = value.getBytes(UTF8_CHARSET); - out.write(bytes); - } - - - @Override - public String deserialize(DataInput in, int available) throws IOException { - if(available==-1) throw new IllegalArgumentException("STRING_NOSIZE does not work with collections."); - byte[] bytes = new byte[available]; - in.readFully(bytes); - return new String(bytes, UTF8_CHARSET); - } - - @Override - public int fixedSize() { - return -1; - } - - }; - - - - - - /** Serializes Long into 8 bytes, used mainly for testing. - * Does not handle null values.*/ - - Serializer LONG = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Long value) throws IOException { - if(value != null) - out.writeLong(value); - } - - @Override - public Long deserialize(DataInput in, int available) throws IOException { - if(available==0) return null; - return in.readLong(); - } - - @Override - public int fixedSize() { - return 8; - } - - }; - - /** Serializes Integer into 4 bytes. - * Does not handle null values.*/ - - Serializer INTEGER = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Integer value) throws IOException { - out.writeInt(value); - } - - @Override - public Integer deserialize(DataInput in, int available) throws IOException { - return in.readInt(); - } - - @Override - public int fixedSize() { - return 4; - } - - }; - - - Serializer BOOLEAN = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Boolean value) throws IOException { - out.writeBoolean(value); - } - - @Override - public Boolean deserialize(DataInput in, int available) throws IOException { - if(available==0) return null; - return in.readBoolean(); - } - - @Override - public int fixedSize() { - return 1; - } - - }; - - - - - /** - * Always throws {@link IllegalAccessError} when invoked. Useful for testing and assertions. - */ - Serializer ILLEGAL_ACCESS = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Object value) throws IOException { - throw new IllegalAccessError(); - } - - @Override - public Object deserialize(DataInput in, int available) throws IOException { - throw new IllegalAccessError(); - } - - @Override - public int fixedSize() { - return -1; - } - - }; - - - /** - * Serializes `byte[]` it adds header which contains size information - */ - Serializer BYTE_ARRAY = new Serializer.Trusted() { - - @Override - public void serialize(DataOutput out, byte[] value) throws IOException { - DataIO.packInt(out,value.length); - out.write(value); - } - - @Override - public byte[] deserialize(DataInput in, int available) throws IOException { - int size = DataIO.unpackInt(in); - byte[] ret = new byte[size]; - in.readFully(ret); - return ret; - } - - @Override - public int fixedSize() { - return -1; - } - - } ; - - /** - * Serializes `byte[]` directly into underlying store - * It does not store size, so it can not be used in Maps and other collections. - */ - Serializer BYTE_ARRAY_NOSIZE = new Serializer.Trusted() { - - @Override - public void serialize(DataOutput out, byte[] value) throws IOException { - if(value==null||value.length==0) return; - out.write(value); - } - - @Override - public byte[] deserialize(DataInput in, int available) throws IOException { - if(available==-1) throw new IllegalArgumentException("BYTE_ARRAY_NOSIZE does not work with collections."); - if(available==0) return null; - byte[] ret = new byte[available]; - in.readFully(ret); - return ret; - } - - @Override - public int fixedSize() { - return -1; - } - - } ; - - /** - * Serializes `char[]` it adds header which contains size information - */ - Serializer CHAR_ARRAY = new Serializer.Trusted() { - - @Override - public void serialize(DataOutput out, char[] value) throws IOException { - DataIO.packInt(out,value.length); - for(char c:value){ - out.writeChar(c); - } - } - - @Override - public char[] deserialize(DataInput in, int available) throws IOException { - final int size = DataIO.unpackInt(in); - char[] ret = new char[size]; - for(int i=0;i INT_ARRAY = new Serializer.Trusted() { - - @Override - public void serialize(DataOutput out, int[] value) throws IOException { - DataIO.packInt(out,value.length); - for(int c:value){ - out.writeInt(c); - } - } - - @Override - public int[] deserialize(DataInput in, int available) throws IOException { - final int size = DataIO.unpackInt(in); - int[] ret = new int[size]; - for(int i=0;i LONG_ARRAY = new Serializer.Trusted() { - - @Override - public void serialize(DataOutput out, long[] value) throws IOException { - DataIO.packInt(out,value.length); - for(long c:value){ - out.writeLong(c); - } - } - - @Override - public long[] deserialize(DataInput in, int available) throws IOException { - final int size = DataIO.unpackInt(in); - long[] ret = new long[size]; - for(int i=0;i DOUBLE_ARRAY = new Serializer.Trusted() { - - @Override - public void serialize(DataOutput out, double[] value) throws IOException { - DataIO.packInt(out,value.length); - for(double c:value){ - out.writeDouble(c); - } - } - - @Override - public double[] deserialize(DataInput in, int available) throws IOException { - final int size = DataIO.unpackInt(in); - double[] ret = new double[size]; - for(int i=0;i JAVA = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Object value) throws IOException { - ObjectOutputStream out2 = new ObjectOutputStream((OutputStream) out); - out2.writeObject(value); - out2.flush(); - } - - @Override - public Object deserialize(DataInput in, int available) throws IOException { - try { - ObjectInputStream in2 = new ObjectInputStream((InputStream) in); - return in2.readObject(); - } catch (ClassNotFoundException e) { - throw new IOException(e); - } - } - - @Override - public int fixedSize() { - return -1; - } - - }; - - /** Serializers {@link java.util.UUID} class */ - Serializer UUID = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, UUID value) throws IOException { - out.writeLong(value.getMostSignificantBits()); - out.writeLong(value.getLeastSignificantBits()); - } - - @Override - public UUID deserialize(DataInput in, int available) throws IOException { - return new UUID(in.readLong(), in.readLong()); - } - - @Override - public int fixedSize() { - return 16; - } - - }; - - Serializer BYTE = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Byte value) throws IOException { - out.writeByte(value); //TODO test all new serialziers - } - - @Override - public Byte deserialize(DataInput in, int available) throws IOException { - return in.readByte(); - } - - @Override - public int fixedSize() { - return 1; - } - } ; - Serializer FLOAT = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Float value) throws IOException { - out.writeFloat(value); //TODO test all new serialziers - } - - @Override - public Float deserialize(DataInput in, int available) throws IOException { - return in.readFloat(); - } - - @Override - public int fixedSize() { - return 4; - } - } ; - - - Serializer DOUBLE = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Double value) throws IOException { - out.writeDouble(value); - } - - @Override - public Double deserialize(DataInput in, int available) throws IOException { - return in.readDouble(); - } - - @Override - public int fixedSize() { - return 8; - } - } ; - - Serializer SHORT = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, Short value) throws IOException { - out.writeShort(value.shortValue()); - } - - @Override - public Short deserialize(DataInput in, int available) throws IOException { - return in.readShort(); - } - - @Override - public int fixedSize() { - return 2; - } - } ; - - Serializer BOOLEAN_ARRAY = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, boolean[] value) throws IOException { - DataIO.packInt(out, value.length);//write the number of booleans not the number of bytes - byte[] a = SerializerBase.booleanToByteArray(value); - out.write(a); - } - - @Override - public boolean[] deserialize(DataInput in, int available) throws IOException { - return SerializerBase.readBooleanArray(DataIO.unpackInt(in), in); - } - - @Override - public int fixedSize() { - return -1; - } - }; - - - - Serializer SHORT_ARRAY = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, short[] value) throws IOException { - DataIO.packInt(out,value.length); - for(short v:value){ - out.writeShort(v); - } - } - - @Override - public short[] deserialize(DataInput in, int available) throws IOException { - short[] ret = new short[DataIO.unpackInt(in)]; - for(int i=0;i FLOAT_ARRAY = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, float[] value) throws IOException { - DataIO.packInt(out,value.length); - for(float v:value){ - out.writeFloat(v); - } - } - - @Override - public float[] deserialize(DataInput in, int available) throws IOException { - float[] ret = new float[DataIO.unpackInt(in)]; - for(int i=0;i BIG_INTEGER = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, BigInteger value) throws IOException { - BYTE_ARRAY.serialize(out,value.toByteArray()); - } - - @Override - public BigInteger deserialize(DataInput in, int available) throws IOException { - return new BigInteger(BYTE_ARRAY.deserialize(in,available)); - } - - @Override - public int fixedSize() { - return -1; - } - } ; - - Serializer BIG_DECIMAL = new Serializer.Trusted() { - @Override - public void serialize(DataOutput out, BigDecimal value) throws IOException { - BYTE_ARRAY.serialize(out,value.unscaledValue().toByteArray()); - DataIO.packInt(out, value.scale()); - } - - @Override - public BigDecimal deserialize(DataInput in, int available) throws IOException { - return new BigDecimal(new BigInteger( - BYTE_ARRAY.deserialize(in,-1)), - DataIO.unpackInt(in)); - } - - @Override - public int fixedSize() { - return -1; - } - } ; - - - Serializer CLASS = new Serializer.Trusted() { - - @Override - public void serialize(DataOutput out, Class value) throws IOException { - out.writeUTF(value.getName()); - } - - @Override - public Class deserialize(DataInput in, int available) throws IOException { - return SerializerPojo.classForName(in.readUTF()); - } - - @Override - public int fixedSize() { - return -1; - } - }; - - Serializer DATE = new Serializer.Trusted() { - - @Override - public void serialize(DataOutput out, Date value) throws IOException { - out.writeLong(value.getTime()); - } - - @Override - public Date deserialize(DataInput in, int available) throws IOException { - return new Date(in.readLong()); - } - - @Override - public int fixedSize() { - return 8; - } - }; - - - /** wraps another serializer and (de)compresses its output/input*/ - public final static class CompressionWrapper implements Serializer.Trusted, Serializable { - - private static final long serialVersionUID = 4440826457939614346L; - protected final Serializer serializer; - protected final ThreadLocal LZF = new ThreadLocal() { - @Override protected CompressLZF initialValue() { - return new CompressLZF(); - } - }; - - public CompressionWrapper(Serializer serializer) { - this.serializer = serializer; - } - - /** used for deserialization */ - protected CompressionWrapper(SerializerBase serializerBase, DataInput is, SerializerBase.FastArrayList objectStack) throws IOException { - objectStack.add(this); - this.serializer = (Serializer) serializerBase.deserialize(is,objectStack); - } - - - @Override - public void serialize(DataOutput out, E value) throws IOException { - DataIO.DataOutputByteArray out2 = new DataIO.DataOutputByteArray(); - serializer.serialize(out2,value); - - byte[] tmp = new byte[out2.pos+41]; - int newLen; - try{ - newLen = LZF.get().compress(out2.buf,out2.pos,tmp,0); - }catch(IndexOutOfBoundsException e){ - newLen=0; //larger after compression - } - if(newLen>=out2.pos){ - //compression adds size, so do not compress - DataIO.packInt(out,0); - out.write(out2.buf,0,out2.pos); - return; - } - - DataIO.packInt(out, out2.pos+1); //unpacked size, zero indicates no compression - out.write(tmp,0,newLen); - } - - @Override - public E deserialize(DataInput in, int available) throws IOException { - final int unpackedSize = DataIO.unpackInt(in)-1; - if(unpackedSize==-1){ - //was not compressed - return serializer.deserialize(in, available>0?available-1:available); - } - - byte[] unpacked = new byte[unpackedSize]; - LZF.get().expand(in,unpacked,0,unpackedSize); - DataIO.DataInputByteArray in2 = new DataIO.DataInputByteArray(unpacked); - E ret = serializer.deserialize(in2,unpackedSize); - if(CC.PARANOID && ! (in2.pos==unpackedSize)) - throw new AssertionError( "data were not fully read"); - return ret; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CompressionWrapper that = (CompressionWrapper) o; - return serializer.equals(that.serializer); - } - - @Override - public int hashCode() { - return serializer.hashCode(); - } - - @Override - public int fixedSize() { - return -1; - } - - } - - //this has to be lazily initialized due to circular dependencies - static final class __BasicInstance { - final static Serializer s = new SerializerBase(); - } - - - /** - * Basic serializer for most classes in 'java.lang' and 'java.util' packages. - * It does not handle custom POJO classes. It also does not handle classes which - * require access to `DB` itself. - */ - @SuppressWarnings("unchecked") - Serializer BASIC = new Serializer.Trusted(){ - - @Override - public void serialize(DataOutput out, Object value) throws IOException { - __BasicInstance.s.serialize(out,value); - } - - @Override - public Object deserialize(DataInput in, int available) throws IOException { - return __BasicInstance.s.deserialize(in,available); - } - - @Override - public int fixedSize() { - return -1; - } - }; - - - /** - * Serialize the content of an object into a ObjectOutput - * - * @param out ObjectOutput to save object into - * @param value Object to serialize - */ - public void serialize( DataOutput out, A value) - throws IOException; - - - /** - * Deserialize the content of an object from a DataInput. - * - * @param in to read serialized data from - * @param available how many bytes are available in DataInput for reading, may be -1 (in streams) or 0 (null). - * @return deserialized object - * @throws java.io.IOException - */ - public A deserialize( DataInput in, int available) - throws IOException; - - /** - * Data could be serialized into record with variable size or fixed size. - * Some optimizations can be applied to serializers with fixed size - * - * @return fixed size or -1 for variable size - */ - public int fixedSize(); - -} diff --git a/src/main/java/org/mapdb/SerializerBase.java b/src/main/java/org/mapdb/SerializerBase.java deleted file mode 100644 index 6e43560c3..000000000 --- a/src/main/java/org/mapdb/SerializerBase.java +++ /dev/null @@ -1,2127 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ -package org.mapdb; - -import java.io.*; -import java.lang.reflect.Array; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.*; - -/** - * Serializer which uses 'header byte' to serialize/deserialize - * most of classes from 'java.lang' and 'java.util' packages. - * - * @author Jan Kotek - */ -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class SerializerBase implements Serializer.Trusted{ - - - protected interface Ser { - /** - * Serialize the content of an object into a ObjectOutput - * - * @param out ObjectOutput to save object into - * @param value Object to serialize - */ - public void serialize( DataOutput out, A value, FastArrayList objectStack) - throws IOException; - } - - protected static abstract class Deser { - - /** - * Deserialize the content of an object from a DataInput. - * - * @param in to read serialized data from - * @return deserialized object - * @throws java.io.IOException - */ - abstract public Object deserialize(DataInput in, FastArrayList objectStack) - throws IOException; - - public boolean needsObjectStack(){ - return false; - } - } - - /** always returns single object without reading anything*/ - protected final class DeserSingleton extends Deser{ - - protected final Object singleton; - - public DeserSingleton(Object singleton) { - this.singleton = singleton; - } - - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return singleton; - } - } - - - protected static final class DeserSerializer extends Deser { - private final Serializer serializer; - - public DeserSerializer(Serializer serializer) { - if(serializer==null) - throw new NullPointerException(); - this.serializer = serializer; - } - - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return serializer.deserialize(in,-1); - } - } - - protected static final class DeserStringLen extends Deser{ - final int len; - - DeserStringLen(int len) { - this.len = len; - } - - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return deserializeString(in,len); - } - } - - - protected static final class DeserInt extends Deser{ - - protected final int digits; - protected final boolean minus; - - public DeserInt(int digits, boolean minus) { - this.digits = digits; - this.minus = minus; - } - - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - int ret = in.readUnsignedByte()&0xFF; - for(int i=1;i ser = new IdentityHashMap(); - - protected final Deser[] headerDeser = new Deser[255]; - - public SerializerBase(){ - initHeaderDeser(); - initSer(); - initMapdb(); - } - - protected void initSer() { - ser.put(Integer.class, SER_INT); - ser.put(Long.class, SER_LONG); - ser.put(String.class, SER_STRING); - ser.put(Boolean.class, SER_BOOLEAN); - ser.put(String.class, SER_STRING); - ser.put(Character.class, SER_CHAR); - ser.put(Short.class, SER_SHORT); - ser.put(Float.class, SER_FLOAT); - ser.put(Double.class, SER_DOUBLE); - ser.put(Byte.class, SER_BYTE); - - ser.put(byte[].class, SER_BYTE_ARRAY); - ser.put(boolean[].class, new SerHeaderSerializer(Header.ARRAY_BOOLEAN, Serializer.BOOLEAN_ARRAY)); - ser.put(short[].class, new SerHeaderSerializer(Header.ARRAY_SHORT, Serializer.SHORT_ARRAY)); - ser.put(char[].class, new SerHeaderSerializer(Header.ARRAY_CHAR, Serializer.CHAR_ARRAY)); - ser.put(float[].class, new SerHeaderSerializer(Header.ARRAY_FLOAT, Serializer.FLOAT_ARRAY)); - ser.put(double[].class, new SerHeaderSerializer(Header.ARRAY_DOUBLE, Serializer.DOUBLE_ARRAY)); - ser.put(int[].class, SER_INT_ARRAY); - ser.put(long[].class, SER_LONG_ARRAY); - - ser.put(BigInteger.class, new SerHeaderSerializer(Header.BIGINTEGER,Serializer.BIG_INTEGER)); - ser.put(BigDecimal.class, new SerHeaderSerializer(Header.BIGDECIMAL,Serializer.BIG_DECIMAL)); - ser.put(Class.class, new SerHeaderSerializer(Header.CLASS,Serializer.CLASS)); - ser.put(Date.class, new SerHeaderSerializer(Header.DATE,Serializer.DATE)); - ser.put(UUID.class, new SerHeaderSerializer(Header.UUID,Serializer.UUID)); - - ser.put(Atomic.Long.class, SER_MA_LONG); - ser.put(Atomic.Integer.class, SER_MA_INT); - ser.put(Atomic.Boolean.class, SER_MA_BOOL); - ser.put(Atomic.String.class, SER_MA_STRING); - ser.put(Atomic.Var.class, SER_MA_VAR); - - ser.put(Object[].class, new Ser(){ - - @Override - public void serialize(DataOutput out, Object[] b, FastArrayList objectStack) throws IOException { - serializeObjectArray(out, b, objectStack); - } - }); - - ser.put(ArrayList.class, new Ser(){ - @Override - public void serialize(DataOutput out, ArrayList value, FastArrayList objectStack) throws IOException { - serializeCollection(Header.ARRAYLIST, out, value, objectStack); - } - }); - - ser.put(LinkedList.class, new Ser(){ - @Override - public void serialize(DataOutput out, Collection value, FastArrayList objectStack) throws IOException { - serializeCollection(Header.LINKEDLIST, out,value, objectStack); - } - }); - - ser.put(HashSet.class, new Ser(){ - @Override - public void serialize(DataOutput out, Collection value, FastArrayList objectStack) throws IOException { - //TODO serialize hash salt to preserve order after deserialization? applies to map as well - serializeCollection(Header.HASHSET, out,value, objectStack); - } - }); - - ser.put(LinkedHashSet.class, new Ser(){ - @Override - public void serialize(DataOutput out, Collection value, FastArrayList objectStack) throws IOException { - serializeCollection(Header.LINKEDHASHSET, out,value, objectStack); - } - }); - - ser.put(HashMap.class, new Ser(){ - @Override - public void serialize(DataOutput out, Map value, FastArrayList objectStack) throws IOException { - serializeMap(Header.HASHMAP, out,value, objectStack); - } - }); - - ser.put(LinkedHashMap.class, new Ser(){ - @Override - public void serialize(DataOutput out, Map value, FastArrayList objectStack) throws IOException { - serializeMap(Header.LINKEDHASHMAP, out,value, objectStack); - } - }); - - ser.put(Properties.class, new Ser(){ - @Override - public void serialize(DataOutput out, Map value, FastArrayList objectStack) throws IOException { - serializeMap(Header.PROPERTIES, out, value, objectStack); - } - }); - - - ser.put(TreeSet.class, new Ser(){ - @Override - public void serialize(DataOutput out, TreeSet l, FastArrayList objectStack) throws IOException { - out.write(Header.TREESET); - DataIO.packInt(out, l.size()); - SerializerBase.this.serialize(out, l.comparator(), objectStack); - for (Object o : l) - SerializerBase.this.serialize(out, o, objectStack); - } - }); - - ser.put(TreeMap.class, new Ser>(){ - @Override - public void serialize(DataOutput out, TreeMap l, FastArrayList objectStack) throws IOException { - out.write(Header.TREEMAP); - DataIO.packInt(out, l.size()); - SerializerBase.this.serialize(out, l.comparator(), objectStack); - for (Map.Entry o : l.entrySet()) { - SerializerBase.this.serialize(out, o.getKey(), objectStack); - SerializerBase.this.serialize(out, o.getValue(), objectStack); - } - } - }); - - ser.put(Fun.Pair.class, new Ser(){ - @Override - public void serialize(DataOutput out, Fun.Pair value, FastArrayList objectStack) throws IOException { - out.write(Header.PAIR); - SerializerBase.this.serialize(out, value.a, objectStack); - SerializerBase.this.serialize(out, value.b, objectStack); - } - }); - - ser.put(BTreeKeySerializer.BasicKeySerializer.class, new Ser(){ - @Override - public void serialize(DataOutput out, BTreeKeySerializer.BasicKeySerializer value, FastArrayList objectStack) throws IOException { - out.write(Header.MAPDB); - DataIO.packInt(out, HeaderMapDB.B_TREE_BASIC_KEY_SERIALIZER); - SerializerBase.this.serialize(out, value.serializer, objectStack); - SerializerBase.this.serialize(out, value.comparator, objectStack); - } - }); - - ser.put(Fun.ArrayComparator.class, new Ser(){ - @Override - public void serialize(DataOutput out, Fun.ArrayComparator value, FastArrayList objectStack) throws IOException { - out.write(Header.MAPDB); - DataIO.packInt(out, HeaderMapDB.COMPARATOR_ARRAY); - SerializerBase.this.serialize(out, value.comparators,objectStack); - } - }); - - ser.put(CompressionWrapper.class, new Ser(){ - @Override - public void serialize(DataOutput out, CompressionWrapper value, FastArrayList objectStack) throws IOException { - out.write(Header.MAPDB); - DataIO.packInt(out, HeaderMapDB.SERIALIZER_COMPRESSION_WRAPPER); - SerializerBase.this.serialize(out, value.serializer,objectStack); - } - }); - ser.put(BTreeKeySerializer.Compress.class, new Ser< BTreeKeySerializer.Compress>(){ - @Override - public void serialize(DataOutput out, BTreeKeySerializer.Compress value, FastArrayList objectStack) throws IOException { - out.write(Header.MAPDB); - DataIO.packInt(out, HeaderMapDB.B_TREE_COMPRESS_KEY_SERIALIZER); - SerializerBase.this.serialize(out, value.wrapped,objectStack); - } - }); - - } - - public void serializeObjectArray(DataOutput out, Object[] b, FastArrayList objectStack) throws IOException { - boolean allNull = true; - //check for all null - for (Object o : b) { - if(o!=null){ - allNull=false; - break; - } - } - - if(allNull){ - out.write(Header.ARRAY_OBJECT_ALL_NULL); - DataIO.packInt(out, b.length); - - // Write class for components - Class componentType = b.getClass().getComponentType(); - serializeClass(out, componentType); - } else { - out.write(Header.ARRAY_OBJECT); - DataIO.packInt(out, b.length); - - // Write class for components - Class componentType = b.getClass().getComponentType(); - serializeClass(out, componentType); - - for (Object o : b) - this.serialize(out, o, objectStack); - - } - } - - protected void initHeaderDeser(){ - - headerDeser[Header.NULL] = new DeserSingleton(null); - headerDeser[Header.ZERO_FAIL] = new Deser() { - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - throw new IOError(new IOException("Zero Header, data corrupted")); - } - }; - headerDeser[Header.JAVA_SERIALIZATION] = new Deser() { - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - throw new IOError(new IOException( - "Wrong header, data were probably serialized with " + - "java.lang.ObjectOutputStream," + - " not with MapDB serialization")); - } - }; - - headerDeser[Header.BOOLEAN_FALSE] = new DeserSingleton(Boolean.FALSE); - headerDeser[Header.BOOLEAN_TRUE] = new DeserSingleton(Boolean.TRUE); - - headerDeser[Header.INT_M9] = new DeserSingleton(-9); - headerDeser[Header.INT_M8] = new DeserSingleton(-8); - headerDeser[Header.INT_M7] = new DeserSingleton(-7); - headerDeser[Header.INT_M6] = new DeserSingleton(-6); - headerDeser[Header.INT_M5] = new DeserSingleton(-5); - headerDeser[Header.INT_M4] = new DeserSingleton(-4); - headerDeser[Header.INT_M3] = new DeserSingleton(-3); - headerDeser[Header.INT_M2] = new DeserSingleton(-2); - headerDeser[Header.INT_M1] = new DeserSingleton(-1); - headerDeser[Header.INT_0] = new DeserSingleton(0); - headerDeser[Header.INT_1] = new DeserSingleton(1); - headerDeser[Header.INT_2] = new DeserSingleton(2); - headerDeser[Header.INT_3] = new DeserSingleton(3); - headerDeser[Header.INT_4] = new DeserSingleton(4); - headerDeser[Header.INT_5] = new DeserSingleton(5); - headerDeser[Header.INT_6] = new DeserSingleton(6); - headerDeser[Header.INT_7] = new DeserSingleton(7); - headerDeser[Header.INT_8] = new DeserSingleton(8); - headerDeser[Header.INT_9] = new DeserSingleton(9); - headerDeser[Header.INT_10] = new DeserSingleton(10); - headerDeser[Header.INT_11] = new DeserSingleton(11); - headerDeser[Header.INT_12] = new DeserSingleton(12); - headerDeser[Header.INT_13] = new DeserSingleton(13); - headerDeser[Header.INT_14] = new DeserSingleton(14); - headerDeser[Header.INT_15] = new DeserSingleton(15); - headerDeser[Header.INT_16] = new DeserSingleton(16); - headerDeser[Header.INT_MIN_VALUE] = new DeserSingleton(Integer.MIN_VALUE); - headerDeser[Header.INT_MAX_VALUE] = new DeserSingleton(Integer.MAX_VALUE); - - headerDeser[Header.LONG_M9] = new DeserSingleton(-9L); - headerDeser[Header.LONG_M8] = new DeserSingleton(-8L); - headerDeser[Header.LONG_M7] = new DeserSingleton(-7L); - headerDeser[Header.LONG_M6] = new DeserSingleton(-6L); - headerDeser[Header.LONG_M5] = new DeserSingleton(-5L); - headerDeser[Header.LONG_M4] = new DeserSingleton(-4L); - headerDeser[Header.LONG_M3] = new DeserSingleton(-3L); - headerDeser[Header.LONG_M2] = new DeserSingleton(-2L); - headerDeser[Header.LONG_M1] = new DeserSingleton(-1L); - headerDeser[Header.LONG_0] = new DeserSingleton(0L); - headerDeser[Header.LONG_1] = new DeserSingleton(1L); - headerDeser[Header.LONG_2] = new DeserSingleton(2L); - headerDeser[Header.LONG_3] = new DeserSingleton(3L); - headerDeser[Header.LONG_4] = new DeserSingleton(4L); - headerDeser[Header.LONG_5] = new DeserSingleton(5L); - headerDeser[Header.LONG_6] = new DeserSingleton(6L); - headerDeser[Header.LONG_7] = new DeserSingleton(7L); - headerDeser[Header.LONG_8] = new DeserSingleton(8L); - headerDeser[Header.LONG_9] = new DeserSingleton(9L); - headerDeser[Header.LONG_10] = new DeserSingleton(10L); - headerDeser[Header.LONG_11] = new DeserSingleton(11L); - headerDeser[Header.LONG_12] = new DeserSingleton(12L); - headerDeser[Header.LONG_13] = new DeserSingleton(13L); - headerDeser[Header.LONG_14] = new DeserSingleton(14L); - headerDeser[Header.LONG_15] = new DeserSingleton(15L); - headerDeser[Header.LONG_16] = new DeserSingleton(16L); - headerDeser[Header.LONG_MIN_VALUE] = new DeserSingleton(Long.MIN_VALUE); - headerDeser[Header.LONG_MAX_VALUE] = new DeserSingleton(Long.MAX_VALUE); - - headerDeser[Header.CHAR_0] = new DeserSingleton((char)0); - headerDeser[Header.CHAR_1] = new DeserSingleton((char)1); - - headerDeser[Header.SHORT_M1] = new DeserSingleton((short)-1); - headerDeser[Header.SHORT_0] = new DeserSingleton((short)0); - headerDeser[Header.SHORT_1] = new DeserSingleton((short)1); - - headerDeser[Header.FLOAT_M1] = new DeserSingleton(-1F); - headerDeser[Header.FLOAT_0] = new DeserSingleton(0F); - headerDeser[Header.FLOAT_1] = new DeserSingleton(1F); - - headerDeser[Header.DOUBLE_M1] = new DeserSingleton(-1D); - headerDeser[Header.DOUBLE_0] = new DeserSingleton(0D); - headerDeser[Header.DOUBLE_1] = new DeserSingleton(1D); - - headerDeser[Header.BYTE_M1] = new DeserSingleton((byte)-1); - headerDeser[Header.BYTE_0] = new DeserSingleton((byte)0); - headerDeser[Header.BYTE_1] = new DeserSingleton((byte)1); - - headerDeser[Header.STRING_0] = new DeserSingleton(""); - - headerDeser[Header.INT] = new DeserSerializer(Serializer.INTEGER); - headerDeser[Header.LONG] = new DeserSerializer(Serializer.LONG); - headerDeser[Header.CHAR] = new DeserSerializer(Serializer.CHAR); - headerDeser[Header.SHORT] = new DeserSerializer(Serializer.SHORT); - headerDeser[Header.FLOAT] = new DeserSerializer(Serializer.FLOAT); - headerDeser[Header.DOUBLE] = new DeserSerializer(Serializer.DOUBLE); - headerDeser[Header.BYTE] = new DeserSerializer(Serializer.BYTE); - - headerDeser[Header.STRING] = new Deser(){ - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return deserializeString(in, DataIO.unpackInt(in)); - } - }; - headerDeser[Header.STRING_1] = new DeserStringLen(1); - headerDeser[Header.STRING_2] = new DeserStringLen(2); - headerDeser[Header.STRING_3] = new DeserStringLen(3); - headerDeser[Header.STRING_4] = new DeserStringLen(4); - headerDeser[Header.STRING_5] = new DeserStringLen(5); - headerDeser[Header.STRING_6] = new DeserStringLen(6); - headerDeser[Header.STRING_7] = new DeserStringLen(7); - headerDeser[Header.STRING_8] = new DeserStringLen(8); - headerDeser[Header.STRING_9] = new DeserStringLen(9); - headerDeser[Header.STRING_10] = new DeserStringLen(10); - - headerDeser[Header.CHAR_255] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return (char) in.readUnsignedByte(); - } - }; - - headerDeser[Header.SHORT_255] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return (short) in.readUnsignedByte(); - } - }; - - headerDeser[Header.SHORT_M255] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return (short) -in.readUnsignedByte(); - } - }; - - headerDeser[Header.FLOAT_255] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return (float) in.readUnsignedByte(); - } - }; - - headerDeser[Header.FLOAT_SHORT] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return (float) in.readShort(); - } - }; - - headerDeser[Header.DOUBLE_255] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return (double) in.readUnsignedByte(); - } - }; - - headerDeser[Header.DOUBLE_SHORT] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return (double) in.readShort(); - } - }; - - headerDeser[Header.DOUBLE_INT] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return (double) in.readInt(); - } - }; - - headerDeser[Header.MA_LONG] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new Atomic.Long(getEngine(),DataIO.unpackLong(in)); - } - }; - - headerDeser[Header.MA_INT] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new Atomic.Integer(getEngine(),DataIO.unpackLong(in)); - } - }; - - headerDeser[Header.MA_BOOL] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new Atomic.Boolean(getEngine(),DataIO.unpackLong(in)); - } - }; - - headerDeser[Header.MA_STRING] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new Atomic.String(getEngine(),DataIO.unpackLong(in)); - } - }; - - headerDeser[Header.MA_VAR] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new Atomic.Var(getEngine(), SerializerBase.this,in, objectStack); - } - - @Override - public boolean needsObjectStack() { - return true; - } - }; - - headerDeser[Header.ARRAY_BYTE_ALL_EQUAL] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - byte[] b = new byte[DataIO.unpackInt(in)]; - Arrays.fill(b, in.readByte()); - return b; - } - }; - - headerDeser[Header.ARRAY_BOOLEAN] = new DeserSerializer(Serializer.BOOLEAN_ARRAY); - headerDeser[Header.ARRAY_INT] = new DeserSerializer(Serializer.INT_ARRAY); - headerDeser[Header.ARRAY_SHORT] = new DeserSerializer(Serializer.SHORT_ARRAY); - headerDeser[Header.ARRAY_DOUBLE] = new DeserSerializer(Serializer.DOUBLE_ARRAY); - headerDeser[Header.ARRAY_FLOAT]= new DeserSerializer(Serializer.FLOAT_ARRAY); - headerDeser[Header.ARRAY_CHAR]= new DeserSerializer(Serializer.CHAR_ARRAY); - headerDeser[Header.ARRAY_BYTE]= new DeserSerializer(Serializer.BYTE_ARRAY); - - headerDeser[Header.ARRAY_INT_BYTE] = new Deser(){ - @Override public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - int[] ret=new int[DataIO.unpackInt(in)]; - for(int i=0;i { - - public int size ; - public K[] data ; - - public FastArrayList(){ - size=0; - data = (K[]) new Object[1]; - } - - public boolean forwardRefs = false; - - - public void add(K o) { - if (data.length == size) { - //grow array if necessary - data = Arrays.copyOf(data, data.length * 2); - } - - data[size] = o; - size++; - } - - - - /** - * This method is reason why ArrayList is not used. - * Search an item in list and returns its index. - * It uses identity rather than 'equalsTo' - * One could argue that TreeMap should be used instead, - * but we do not expect large object trees. - * This search is VERY FAST compared to Maps, it does not allocate - * new instances or uses method calls. - * - * @param obj to find in list - * @return index of object in list or -1 if not found - */ - public int identityIndexOf(Object obj) { - for (int i = 0; i < size; i++) { - if (obj == data[i]){ - forwardRefs = true; - return i; - } - } - return -1; - } - - } - - - - - @Override - public void serialize(final DataOutput out, final Object obj) throws IOException { - serialize(out, obj, new FastArrayList()); - } - - - public void serialize(final DataOutput out, final Object obj, FastArrayList objectStack) throws IOException { - - if (obj == null) { - out.write(Header.NULL); - return; - } - - /**try to find object on stack if it exists*/ - if (objectStack != null) { - int indexInObjectStack = objectStack.identityIndexOf(obj); - if (indexInObjectStack != -1) { - //object was already serialized, just write reference to it and return - out.write(Header.OBJECT_STACK); - DataIO.packInt(out, indexInObjectStack); - return; - } - //add this object to objectStack - objectStack.add(obj); - } - - - //Object[] and String[] are two different classes, - // so getClass()==getClass() fails, but instanceof works - // so special treatment for non-primitive arrays - if(obj instanceof Object[]){ - serializeObjectArray(out, (Object[]) obj, objectStack); - return; - } - - if(obj == SerializerBase.this){ - out.write(Header.MAPDB); - out.write(HeaderMapDB.THIS_SERIALIZER); - return; - } - - //try mapdb singletons - final Integer mapdbSingletonHeader = mapdb_all.get(obj); - if(mapdbSingletonHeader!=null){ - out.write(Header.MAPDB); - DataIO.packInt(out, mapdbSingletonHeader); - return; - } - - Ser s = ser.get(obj.getClass()); - if(s!=null){ - s.serialize(out,obj,objectStack); - return; - } - - //unknown clas - serializeUnknownObject(out,obj,objectStack); - } - - - protected static final Ser SER_STRING = new Ser(){ - @Override - public void serialize(DataOutput out, String value, FastArrayList objectStack) throws IOException { - int len = value.length(); - if(len == 0){ - out.write(Header.STRING_0); - }else{ - if (len<=10){ - out.write(Header.STRING_0+len); - }else{ - out.write(Header.STRING); - DataIO.packInt(out, len); - } - for (int i = 0; i < len; i++) - DataIO.packInt(out,(int)(value.charAt(i))); - } - } - }; - - protected static final Ser SER_LONG_ARRAY = new Ser() { - @Override - public void serialize(DataOutput out, long[] val, FastArrayList objectStack) throws IOException { - - long max = Long.MIN_VALUE; - long min = Long.MAX_VALUE; - for (long i : val) { - max = Math.max(max, i); - min = Math.min(min, i); - } - if (Byte.MIN_VALUE <= min && max <= Byte.MAX_VALUE) { - out.write(Header.ARRAY_LONG_BYTE); - DataIO.packInt(out, val.length); - for (long i : val) out.write((int) i); - } else if (Short.MIN_VALUE <= min && max <= Short.MAX_VALUE) { - out.write(Header.ARRAY_LONG_SHORT); - DataIO.packInt(out, val.length); - for (long i : val) out.writeShort((int) i); - } else if (0 <= min) { - out.write(Header.ARRAY_LONG_PACKED); - DataIO.packInt(out, val.length); - for (long l : val) DataIO.packLong(out, l); - } else if (Integer.MIN_VALUE <= min && max <= Integer.MAX_VALUE) { - out.write(Header.ARRAY_LONG_INT); - DataIO.packInt(out, val.length); - for (long i : val) out.writeInt((int) i); - } else { - out.write(Header.ARRAY_LONG); - DataIO.packInt(out, val.length); - for (long i : val) out.writeLong(i); - } - } - }; - - protected static final Ser SER_INT_ARRAY = new Ser() { - @Override - public void serialize(DataOutput out, int[] val, FastArrayList objectStack) throws IOException { - - int max = Integer.MIN_VALUE; - int min = Integer.MAX_VALUE; - for (int i : val) { - max = Math.max(max, i); - min = Math.min(min, i); - } - if (Byte.MIN_VALUE <= min && max <= Byte.MAX_VALUE) { - out.write(Header.ARRAY_INT_BYTE); - DataIO.packInt(out, val.length); - for (int i : val) out.write(i); - } else if (Short.MIN_VALUE <= min && max <= Short.MAX_VALUE) { - out.write(Header.ARRAY_INT_SHORT); - DataIO.packInt(out, val.length); - for (int i : val) out.writeShort(i); - } else if (0 <= min) { - out.write(Header.ARRAY_INT_PACKED); - DataIO.packInt(out, val.length); - for (int l : val) DataIO.packInt(out, l); - } else { - out.write(Header.ARRAY_INT); - DataIO.packInt(out, val.length); - for (int i : val) out.writeInt(i); - } - } - }; - - protected static final Ser SER_DOUBLE = new Ser() { - @Override - public void serialize(DataOutput out, Double value, FastArrayList objectStack) throws IOException { - double v = value; - if (v == -1D) { - out.write(Header.DOUBLE_M1); - } else if (v == 0D) { - out.write(Header.DOUBLE_0); - } else if (v == 1D) { - out.write(Header.DOUBLE_1); - } else if (v >= 0 && v <= 255 && value.intValue() == v) { - out.write(Header.DOUBLE_255); - out.write(value.intValue()); - } else if (value.shortValue() == v) { - out.write(Header.DOUBLE_SHORT); - out.writeShort(value.shortValue()); - } else if (value.intValue() == v) { - out.write(Header.DOUBLE_INT); - out.writeInt(value.intValue()); - } else { - out.write(Header.DOUBLE); - out.writeDouble(v); - } - } - }; - - protected static final Ser SER_FLOAT = new Ser() { - @Override - public void serialize(DataOutput out, Float value, FastArrayList objectStack) throws IOException { - float v = value; - if (v == -1f) - out.write(Header.FLOAT_M1); - else if (v == 0f) - out.write(Header.FLOAT_0); - else if (v == 1f) - out.write(Header.FLOAT_1); - else if (v >= 0 && v <= 255 && value.intValue() == v) { - out.write(Header.FLOAT_255); - out.write(value.intValue()); - } else if (v >= Short.MIN_VALUE && v <= Short.MAX_VALUE && value.shortValue() == v) { - out.write(Header.FLOAT_SHORT); - out.writeShort(value.shortValue()); - } else { - out.write(Header.FLOAT); - out.writeFloat(v); - } - } - }; - - protected static final Ser SER_SHORT = new Ser() { - @Override - public void serialize(DataOutput out, Short value, FastArrayList objectStack) throws IOException { - - short val = value; - if (val == -1) { - out.write(Header.SHORT_M1); - } else if (val == 0) { - out.write(Header.SHORT_0); - } else if (val == 1) { - out.write(Header.SHORT_1); - } else if (val > 0 && val < 255) { - out.write(Header.SHORT_255); - out.write(val); - } else if (val < 0 && val > -255) { - out.write(Header.SHORT_M255); - out.write(-val); - } else { - out.write(Header.SHORT); - out.writeShort(val); - } - } - }; - - protected static final Ser SER_CHAR = new Ser() { - @Override - public void serialize(DataOutput out, Character value, FastArrayList objectStack) throws IOException { - char val = value; - if (val == 0) { - out.write(Header.CHAR_0); - } else if (val == 1) { - out.write(Header.CHAR_1); - } else if (val <= 255) { - out.write(Header.CHAR_255); - out.write(val); - } else { - out.write(Header.CHAR); - out.writeChar(val); - } - } - }; - - protected static final Ser SER_BYTE= new Ser() { - @Override - public void serialize(DataOutput out, Byte value, FastArrayList objectStack) throws IOException { - byte val = value; - if (val == -1) - out.write(Header.BYTE_M1); - else if (val == 0) - out.write(Header.BYTE_0); - else if (val == 1) - out.write(Header.BYTE_1); - else { - out.write(Header.BYTE); - out.writeByte(val); - } - } - }; - protected static final Ser SER_BOOLEAN = new Ser() { - @Override - public void serialize(DataOutput out, Boolean value, FastArrayList objectStack) throws IOException { - out.write(value ? Header.BOOLEAN_TRUE : Header.BOOLEAN_FALSE); - } - }; - - - protected static final Ser SER_LONG = new Ser() { - @Override - public void serialize(DataOutput out, Long value, FastArrayList objectStack) throws IOException { - long val = value; - if (val >= -9 && val <= 16) { - out.write((int) (Header.LONG_M9 + (val + 9))); - return; - } else if (val == Long.MIN_VALUE) { - out.write(Header.LONG_MIN_VALUE); - return; - } else if (val == Long.MAX_VALUE) { - out.write(Header.LONG_MAX_VALUE); - return; - } else if (((Math.abs(val) >>> 56) & 0xFF) != 0) { - out.write(Header.LONG); - out.writeLong(val); - return; - } - - int neg = 0; - if (val < 0) { - neg = -1; - val = -val; - } - - //calculate N bytes - int size = 48; - while (((val >> size) & 0xFFL) == 0) { - size -= 8; - } - - //write header - out.write(Header.LONG_F1 + (size / 8) * 2 + neg); - - //write data - while (size >= 0) { - out.write((int) ((val >> size) & 0xFFL)); - size -= 8; - } - } - }; - - protected static final Ser SER_INT = new Ser() { - @Override - public void serialize(DataOutput out, Integer value, FastArrayList objectStack) throws IOException { - int val = value; - switch (val) { - case -9: - case -8: - case -7: - case -6: - case -5: - case -4: - case -3: - case -2: - case -1: - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - out.write((Header.INT_M9 + (val + 9))); - return; - case Integer.MIN_VALUE: - out.write(Header.INT_MIN_VALUE); - return; - case Integer.MAX_VALUE: - out.write(Header.INT_MAX_VALUE); - return; - - } - if (((Math.abs(val) >>> 24) & 0xFF) != 0) { - out.write(Header.INT); - out.writeInt(val); - return; - } - - int neg = 0; - if (val < 0) { - neg = -1; - val = -val; - } - - //calculate N bytes - int size = 24; - while (((val >> size) & 0xFFL) == 0) { - size -= 8; - } - - //write header - out.write(Header.INT_F1 + (size / 8) * 2 + neg); - - //write data - while (size >= 0) { - out.write((int) ((val >> size) & 0xFFL)); - size -= 8; - } - } - }; - - protected static final Ser SER_MA_LONG = new Ser(){ - @Override public void serialize(DataOutput out, Atomic.Long value, FastArrayList objectStack) throws IOException { - out.write(Header.MA_LONG); - DataIO.packLong(out,value.recid); - } - }; - - protected static final Ser SER_MA_INT = new Ser(){ - @Override public void serialize(DataOutput out, Atomic.Integer value, FastArrayList objectStack) throws IOException { - out.write(Header.MA_INT); - DataIO.packLong(out,value.recid); - } - }; - - protected static final Ser SER_MA_BOOL = new Ser(){ - @Override public void serialize(DataOutput out, Atomic.Boolean value, FastArrayList objectStack) throws IOException { - out.write(Header.MA_BOOL); - DataIO.packLong(out,value.recid); - } - }; - - protected static final Ser SER_MA_STRING = new Ser(){ - @Override public void serialize(DataOutput out, Atomic.String value, FastArrayList objectStack) throws IOException { - out.write(Header.MA_STRING); - DataIO.packLong(out,value.recid); - } - }; - - protected final Ser SER_MA_VAR = new Ser(){ - - @Override - public void serialize(DataOutput out, Atomic.Var value, FastArrayList objectStack) throws IOException { - out.write(Header.MA_VAR); - DataIO.packLong(out,value.recid); - SerializerBase.this.serialize(out,value.serializer,objectStack); - } - - }; - - - protected void serializeClass(DataOutput out, Class clazz) throws IOException { - //TODO override in SerializerPojo - out.writeUTF(clazz.getName()); - } - - - private void serializeMap(int header, DataOutput out, Object obj, FastArrayList objectStack) throws IOException { - Map l = (Map) obj; - out.write(header); - DataIO.packInt(out, l.size()); - for (Map.Entry o : l.entrySet()) { - serialize(out, o.getKey(), objectStack); - serialize(out, o.getValue(), objectStack); - } - } - - private void serializeCollection(int header, DataOutput out, Object obj, FastArrayList objectStack) throws IOException { - Collection l = (Collection) obj; - out.write(header); - DataIO.packInt(out, l.size()); - - for (Object o : l) - serialize(out, o, objectStack); - - } - - - protected static final Ser SER_BYTE_ARRAY = new Ser() { - @Override - public void serialize(DataOutput out, byte[] b, FastArrayList objectStack) throws IOException { - boolean allEqual = b.length>0; - //check if all values in byte[] are equal - for(int i=1;i()); - } - - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - - final int head = in.readUnsignedByte(); - - int oldObjectStackSize = objectStack.size; - - Object ret = null; - Deser deser = headerDeser[head]; - if(deser!=null){ - ret = deser.deserialize(in, objectStack); - }else{ - ret = deserializeUnknownHeader(in, head,objectStack); - } - - if (head != Header.OBJECT_STACK && ret!=null && objectStack.size == oldObjectStackSize) { - //check if object was not already added to stack as part of collection - objectStack.add(ret); - } - - return ret; - } - - protected interface HeaderMapDB{ - int SERIALIZER_KEY_TUPLE = 56; - int THIS_SERIALIZER = 57; - int B_TREE_BASIC_KEY_SERIALIZER = 58; - int COMPARATOR_ARRAY = 59; - int SERIALIZER_COMPRESSION_WRAPPER = 60; - int B_TREE_COMPRESS_KEY_SERIALIZER = 64; - } - - - protected final Map mapdb_all = new IdentityHashMap(); - protected final LongHashMap mapdb_reverse = new LongHashMap(); - - protected void initMapdb(){ - - /* - * !!!! IMPORTANT !!!! - * Code bellow defines storage format, do not modify!!! - * !!!! IMPORTANT !!!! - */ - - mapdb_add(1, BTreeKeySerializer.STRING); - mapdb_add(2, BTreeKeySerializer.STRING2); - mapdb_add(3, BTreeKeySerializer.LONG); - mapdb_add(4, BTreeKeySerializer.INTEGER); - mapdb_add(5, BTreeKeySerializer.UUID); - - mapdb_add(6, Fun.COMPARATOR); - - mapdb_add(7, Fun.REVERSE_COMPARATOR); - mapdb_add(8, Fun.EMPTY_ITERATOR); - mapdb_add(9, Fun.ThreadFactory.BASIC); - - mapdb_add(10, Serializer.STRING_NOSIZE); - mapdb_add(11, Serializer.STRING_ASCII); - mapdb_add(12, Serializer.STRING_INTERN); - mapdb_add(13, Serializer.LONG); - mapdb_add(14, Serializer.INTEGER); - mapdb_add(15, Serializer.ILLEGAL_ACCESS); - mapdb_add(16, Serializer.BASIC); - mapdb_add(17, Serializer.BOOLEAN); - mapdb_add(18, Serializer.BYTE_ARRAY_NOSIZE); - mapdb_add(19, Serializer.BYTE_ARRAY); - mapdb_add(20, Serializer.JAVA); - mapdb_add(21, Serializer.UUID); - mapdb_add(22, Serializer.STRING); - mapdb_add(23, Serializer.CHAR_ARRAY); - mapdb_add(24, Serializer.INT_ARRAY); - mapdb_add(25, Serializer.LONG_ARRAY); - mapdb_add(26, Serializer.DOUBLE_ARRAY); - - mapdb_add(27, Hasher.BASIC); - mapdb_add(28, Hasher.BYTE_ARRAY); - mapdb_add(29, Hasher.CHAR_ARRAY); - mapdb_add(30, Hasher.INT_ARRAY); - mapdb_add(31, Hasher.LONG_ARRAY); - mapdb_add(32, Hasher.DOUBLE_ARRAY); - mapdb_add(33, Hasher.ARRAY); - - mapdb_add(34, Fun.BYTE_ARRAY_COMPARATOR); - mapdb_add(35, Fun.CHAR_ARRAY_COMPARATOR); - mapdb_add(36, Fun.INT_ARRAY_COMPARATOR); - mapdb_add(37, Fun.LONG_ARRAY_COMPARATOR); - mapdb_add(38, Fun.DOUBLE_ARRAY_COMPARATOR); - mapdb_add(39, Fun.COMPARABLE_ARRAY_COMPARATOR); - - mapdb_add(40, Fun.RECORD_ALWAYS_TRUE); - - mapdb_add(41, BTreeKeySerializer.ARRAY2); - mapdb_add(42, BTreeKeySerializer.ARRAY3); - mapdb_add(43, BTreeKeySerializer.ARRAY4); - - mapdb_add(44, Serializer.CHAR); - mapdb_add(45, Serializer.BYTE); - mapdb_add(46, Serializer.FLOAT); - mapdb_add(47, Serializer.DOUBLE); - mapdb_add(48, Serializer.SHORT); - - mapdb_add(49, Serializer.BOOLEAN_ARRAY); - mapdb_add(50, Serializer.SHORT_ARRAY); - mapdb_add(51, Serializer.FLOAT_ARRAY); - - mapdb_add(52, Serializer.BIG_INTEGER); - mapdb_add(53, Serializer.BIG_DECIMAL); - mapdb_add(54, Serializer.CLASS); - mapdb_add(55, Serializer.DATE); - - //56 - mapdb_add(HeaderMapDB.SERIALIZER_KEY_TUPLE, new Deser() { - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new BTreeKeySerializer.ArrayKeySerializer(SerializerBase.this, in, objectStack); - } - - @Override - public boolean needsObjectStack() { - return true; - } - }); - //57 - mapdb_add(HeaderMapDB.THIS_SERIALIZER, new Deser() { - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return SerializerBase.this; - } - }); - - //58 - mapdb_add(HeaderMapDB.B_TREE_BASIC_KEY_SERIALIZER, new Deser() { - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new BTreeKeySerializer.BasicKeySerializer(SerializerBase.this, in, objectStack); - } - }); - - //59 - mapdb_add(HeaderMapDB.COMPARATOR_ARRAY, new Deser() { - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new Fun.ArrayComparator(SerializerBase.this, in, objectStack); - } - - @Override - public boolean needsObjectStack() { - return true; - } - }); - - //60 - mapdb_add(HeaderMapDB.SERIALIZER_COMPRESSION_WRAPPER, new Deser() { - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new CompressionWrapper(SerializerBase.this, in, objectStack); - } - - @Override - public boolean needsObjectStack() { - return true; - } - }); - - mapdb_add(61, BTreeKeySerializer.BASIC); - mapdb_add(62, BTreeKeySerializer.BYTE_ARRAY); - mapdb_add(63, BTreeKeySerializer.BYTE_ARRAY2); - - //64 - mapdb_add(HeaderMapDB.B_TREE_COMPRESS_KEY_SERIALIZER, new Deser() { - @Override - public Object deserialize(DataInput in, FastArrayList objectStack) throws IOException { - return new BTreeKeySerializer.Compress(SerializerBase.this, in, objectStack); - } - }); - - } - - - private void mapdb_add(int header, Object singleton) { - Object old = mapdb_all.put(singleton,header); - Object old2 = mapdb_reverse.put(header,singleton); - - if(old!=null || old2!=null) - throw new AssertionError("singleton serializer conflict"); - } - - - public void assertSerializable(Object o){ - if(o!=null && !(o instanceof Serializable) - && !mapdb_all.containsKey(o)){ - throw new IllegalArgumentException("Not serializable: "+o.getClass()); - } - } - - - protected Object deserializeMapDB(DataInput is, FastArrayList objectStack) throws IOException { - int head = DataIO.unpackInt(is); - - Object singleton = mapdb_reverse.get(head); - if(singleton == null){ - throw new IOError(new IOException("Unknown header byte, data corrupted")); - } - - if(singleton instanceof Deser){ - singleton = ((Deser)singleton).deserialize(is,objectStack); - } - - return singleton; - } - - protected Engine getEngine(){ - throw new UnsupportedOperationException(); - } - - - protected Class deserializeClass(DataInput is) throws IOException { - //TODO override 'deserializeClass' in SerializerPojo - return SerializerPojo.classForName(is.readUTF()); - } - - - - - - private Object[] deserializeArrayObject(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - Class clazz = deserializeClass(is); - Object[] s = (Object[]) Array.newInstance(clazz, size); - objectStack.add(s); - for (int i = 0; i < size; i++){ - s[i] = deserialize(is, objectStack); - } - return s; - } - - - private ArrayList deserializeArrayList(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - ArrayList s = new ArrayList(size); - objectStack.add(s); - for (int i = 0; i < size; i++) { - s.add(deserialize(is, objectStack)); - } - return s; - } - - - private java.util.LinkedList deserializeLinkedList(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - java.util.LinkedList s = new java.util.LinkedList(); - objectStack.add(s); - for (int i = 0; i < size; i++) - s.add(deserialize(is, objectStack)); - return s; - } - - - - - private HashSet deserializeHashSet(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - HashSet s = new HashSet(size); - objectStack.add(s); - for (int i = 0; i < size; i++) - s.add(deserialize(is, objectStack)); - return s; - } - - - private LinkedHashSet deserializeLinkedHashSet(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - LinkedHashSet s = new LinkedHashSet(size); - objectStack.add(s); - for (int i = 0; i < size; i++) - s.add(deserialize(is, objectStack)); - return s; - } - - - private TreeSet deserializeTreeSet(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - TreeSet s = new TreeSet(); - objectStack.add(s); - Comparator comparator = (Comparator) deserialize(is, objectStack); - if (comparator != null) - s = new TreeSet(comparator); - - for (int i = 0; i < size; i++) - s.add(deserialize(is, objectStack)); - return s; - } - - - private TreeMap deserializeTreeMap(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - - TreeMap s = new TreeMap(); - objectStack.add(s); - Comparator comparator = (Comparator) deserialize(is, objectStack); - if (comparator != null) - s = new TreeMap(comparator); - for (int i = 0; i < size; i++) - s.put(deserialize(is, objectStack), deserialize(is, objectStack)); - return s; - } - - - private HashMap deserializeHashMap(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - - HashMap s = new HashMap(size); - objectStack.add(s); - for (int i = 0; i < size; i++) - s.put(deserialize(is, objectStack), deserialize(is, objectStack)); - return s; - } - - - private LinkedHashMap deserializeLinkedHashMap(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - - LinkedHashMap s = new LinkedHashMap(size); - objectStack.add(s); - for (int i = 0; i < size; i++) - s.put(deserialize(is, objectStack), deserialize(is, objectStack)); - return s; - } - - - - private Properties deserializeProperties(DataInput is, FastArrayList objectStack) throws IOException { - int size = DataIO.unpackInt(is); - - Properties s = new Properties(); - objectStack.add(s); - for (int i = 0; i < size; i++) - s.put(deserialize(is, objectStack), deserialize(is, objectStack)); - return s; - } - - /** override this method to extend SerializerBase functionality*/ - protected void serializeUnknownObject(DataOutput out, Object obj, FastArrayList objectStack) throws IOException { - throw new AssertionError("Could not serialize unknown object: "+obj.getClass().getName()); - } - /** override this method to extend SerializerBase functionality*/ - protected Object deserializeUnknownHeader(DataInput is, int head, FastArrayList objectStack) throws IOException { - throw new AssertionError("Unknown serialization header: " + head); - } - - /** - * Builds a byte array from the array of booleans, compressing up to 8 booleans per byte. - * - * Author of this method is Chris Alexander. - * - * @param bool The booleans to be compressed. - * @return The fully compressed byte array. - */ - protected static byte[] booleanToByteArray(boolean[] bool) { - int boolLen = bool.length; - int mod8 = boolLen%8; - byte[] boolBytes = new byte[(boolLen/8)+((boolLen%8 == 0)?0:1)]; - - boolean isFlushWith8 = mod8 == 0; - int length = (isFlushWith8)?boolBytes.length:boolBytes.length-1; - int x = 0; - int boolByteIndex; - for (boolByteIndex=0; boolByteIndex 1) { - b |= ((bool[x++]? 0x01 : 0x00) << 1); - if (mod8 > 2) { - b |= ((bool[x++]? 0x01 : 0x00) << 2); - if (mod8 > 3) { - b |= ((bool[x++]? 0x01 : 0x00) << 3); - if (mod8 > 4) { - b |= ((bool[x++]? 0x01 : 0x00) << 4); - if (mod8 > 5) { - b |= ((bool[x++]? 0x01 : 0x00) << 5); - if (mod8 > 6) { - b |= ((bool[x++]? 0x01 : 0x00) << 6); - if (mod8 > 7) { - b |= ((bool[x++]? 0x01 : 0x00) << 7); - } - } - } - } - } - } - } - */ - boolBytes[boolByteIndex++] = b; - } - - return boolBytes; - } - - - - /** - * Unpacks an integer from the DataInput indicating the number of booleans that are compressed. It then calculates - * the number of bytes, reads them in, and decompresses and converts them into an array of booleans using the - * toBooleanArray(byte[]); method. The array of booleans are trimmed to numBools elements. This is - * necessary in situations where the number of booleans is not a multiple of 8. - * - * Author of this method is Chris Alexander. - * - * @return The boolean array decompressed from the bytes read in. - * @throws IOException If an error occurred while reading. - */ - protected static boolean[] readBooleanArray(int numBools,DataInput is) throws IOException { - int length = (numBools/8)+((numBools%8 == 0)?0:1); - byte[] boolBytes = new byte[length]; - is.readFully(boolBytes); - - - boolean[] tmp = new boolean[boolBytes.length*8]; - int len = boolBytes.length; - int boolIndex = 0; - for (byte boolByte : boolBytes) { - for (int y = 0; y < 8; y++) { - tmp[boolIndex++] = (boolByte & (0x01 << y)) != 0x00; - } - } - - //Trim excess booleans - boolean[] finalBoolArray = new boolean[numBools]; - System.arraycopy(tmp, 0, finalBoolArray, 0, numBools); - - //Return the trimmed, uncompressed boolean array - return finalBoolArray; - } - - - - - - /** - * Header byte, is used at start of each record to indicate data type - * WARNING !!! values bellow must be unique !!!!! - * - * @author Jan Kotek - */ - protected interface Header { - - int ZERO_FAIL=0; //zero is invalid value, so it fails with uninitialized values - int NULL = 1; - int BOOLEAN_TRUE = 2; - int BOOLEAN_FALSE = 3; - - int INT_M9 = 4; - int INT_M8 = 5; - int INT_M7 = 6; - int INT_M6 = 7; - int INT_M5 = 8; - int INT_M4 = 9; - int INT_M3 = 10; - int INT_M2 = 11; - int INT_M1 = 12; - int INT_0 = 13; - int INT_1 = 14; - int INT_2 = 15; - int INT_3 = 16; - int INT_4 = 17; - int INT_5 = 18; - int INT_6 = 19; - int INT_7 = 20; - int INT_8 = 21; - int INT_9 = 22; - int INT_10 = 23; - int INT_11 = 24; - int INT_12 = 25; - int INT_13 = 26; - int INT_14 = 27; - int INT_15 = 28; - int INT_16 = 29; - int INT_MIN_VALUE = 30; - int INT_MAX_VALUE = 31; - int INT_MF1 = 32; - int INT_F1 = 33; - int INT_MF2 = 34; - int INT_F2 = 35; - int INT_MF3 = 36; - int INT_F3 = 37; - int INT = 38; - - int LONG_M9 = 39; - int LONG_M8 = 40; - int LONG_M7 = 41; - int LONG_M6 = 42; - int LONG_M5 = 43; - int LONG_M4 = 44; - int LONG_M3 = 45; - int LONG_M2 = 46; - int LONG_M1 = 47; - int LONG_0 = 48; - int LONG_1 = 49; - int LONG_2 = 50; - int LONG_3 = 51; - int LONG_4 = 52; - int LONG_5 = 53; - int LONG_6 = 54; - int LONG_7 = 55; - int LONG_8 = 56; - int LONG_9 = 57; - int LONG_10 = 58; - int LONG_11 = 59; - int LONG_12 = 60; - int LONG_13 = 61; - int LONG_14 = 62; - int LONG_15 = 63; - int LONG_16 = 64; - int LONG_MIN_VALUE = 65; - int LONG_MAX_VALUE = 66; - - int LONG_MF1 = 67; - int LONG_F1 = 68; - int LONG_MF2 = 69; - int LONG_F2 = 70; - int LONG_MF3 = 71; - int LONG_F3 = 72; - int LONG_MF4 = 73; - int LONG_F4 = 74; - int LONG_MF5 = 75; - int LONG_F5 = 76; - int LONG_MF6 = 77; - int LONG_F6 = 78; - int LONG_MF7 = 79; - int LONG_F7 = 80; - int LONG = 81; - - int BYTE_M1 = 82; - int BYTE_0 = 83; - int BYTE_1 = 84; - int BYTE = 85; - - int CHAR_0 = 86; - int CHAR_1 = 87; - int CHAR_255 = 88; - int CHAR = 89; - - int SHORT_M1 =90; - int SHORT_0 = 91; - int SHORT_1 = 92; - int SHORT_255 = 93; - int SHORT_M255 = 94; - int SHORT = 95; - - int FLOAT_M1 = 96; - int FLOAT_0 = 97; - int FLOAT_1 = 98; - int FLOAT_255 = 99; - int FLOAT_SHORT = 100; - int FLOAT = 101; - - int DOUBLE_M1 = 102; - int DOUBLE_0 = 103; - int DOUBLE_1 = 104; - int DOUBLE_255 = 105; - int DOUBLE_SHORT = 106; - int DOUBLE_INT = 107; - int DOUBLE = 108; - - int ARRAY_BYTE = 109; - int ARRAY_BYTE_ALL_EQUAL = 110; - - int ARRAY_BOOLEAN = 111; - int ARRAY_SHORT = 112; - int ARRAY_CHAR = 113; - int ARRAY_FLOAT = 114; - int ARRAY_DOUBLE = 115; - - int ARRAY_INT_BYTE = 116; - int ARRAY_INT_SHORT = 117; - int ARRAY_INT_PACKED = 118; - int ARRAY_INT = 119; - - int ARRAY_LONG_BYTE = 120; - int ARRAY_LONG_SHORT = 121; - int ARRAY_LONG_PACKED = 122; - int ARRAY_LONG_INT = 123; - int ARRAY_LONG = 124; - - int STRING_0 = 125; - int STRING_1 = 126; - int STRING_2 = 127; - int STRING_3 = 128; - int STRING_4 = 129; - int STRING_5 = 130; - int STRING_6 = 131; - int STRING_7 = 132; - int STRING_8 = 133; - int STRING_9 = 134; - int STRING_10 = 135; - int STRING = 136; - - int BIGDECIMAL = 137; - int BIGINTEGER = 138; - - - int CLASS = 139; - int DATE = 140; -// int FUN_HI = 141; - int UUID = 142; - - //144 to 149 reserved for other non recursive objects - - int MAPDB = 150; - int PAIR = 151; -// int TUPLE3 = 152; //TODO unused -// int TUPLE4 = 153; -// int TUPLE5 = 154; //reserved for Tuple5 if we will ever implement it -// int TUPLE6 = 155; //reserved for Tuple6 if we will ever implement it -// int TUPLE7 = 156; //reserved for Tuple7 if we will ever implement it -// int TUPLE8 = 157; //reserved for Tuple8 if we will ever implement it - - - int ARRAY_OBJECT = 158; - //special cases for BTree values which stores references -// int ARRAY_OBJECT_PACKED_LONG = 159; TODO unused -// int ARRAYLIST_PACKED_LONG = 160; - int ARRAY_OBJECT_ALL_NULL = 161; - int ARRAY_OBJECT_NO_REFS = 162; - - int ARRAYLIST = 163; - int TREEMAP = 164; - int HASHMAP = 165; - int LINKEDHASHMAP = 166; - int TREESET = 167; - int HASHSET = 168; - int LINKEDHASHSET = 169; - int LINKEDLIST = 170; - int PROPERTIES = 171; - - /** - * Value used in Java Serialization header. For this header we throw an exception because data might be corrupted - */ - int JAVA_SERIALIZATION = 172; - - /** - * Use POJO Serializer to get class structure and set its fields - */ - int POJO = 173; - /** - * used for reference to already serialized object in object graph - */ - int OBJECT_STACK = 174; - - /** - * reference to named object - */ - int NAMED = 175; - - int MA_LONG = 176; - int MA_INT = 177; - int MA_BOOL = 178; - int MA_STRING = 179; - int MA_VAR = 180; - - } - - @Override - public int fixedSize() { - return -1; - } - - -} diff --git a/src/main/java/org/mapdb/SerializerPojo.java b/src/main/java/org/mapdb/SerializerPojo.java deleted file mode 100644 index b2328fad9..000000000 --- a/src/main/java/org/mapdb/SerializerPojo.java +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ -package org.mapdb; - -import java.io.*; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * Serializer which handles POJO, object graphs etc. - * - * @author Jan Kotek - */ -public class SerializerPojo extends SerializerBase implements Serializable{ - - - protected static final Serializer> serializer = new Serializer.Trusted>() { - - @Override - public void serialize(DataOutput out, CopyOnWriteArrayList obj) throws IOException { - DataIO.packInt(out, obj.size()); - for (ClassInfo ci : obj) { - out.writeUTF(ci.name); - out.writeBoolean(ci.isEnum); - out.writeBoolean(ci.useObjectStream); - if(ci.useObjectStream) continue; //no fields - - DataIO.packInt(out, ci.fields.size()); - for (FieldInfo fi : ci.fields) { - out.writeUTF(fi.name); - out.writeBoolean(fi.primitive); - out.writeUTF(fi.type); - } - } - } - - @Override - public CopyOnWriteArrayList deserialize(DataInput in, int available) throws IOException{ - if(available==0) return new CopyOnWriteArrayList(); - - int size = DataIO.unpackInt(in); - ArrayList ret = new ArrayList(size); - - for (int i = 0; i < size; i++) { - String className = in.readUTF(); - boolean isEnum = in.readBoolean(); - boolean isExternalizable = in.readBoolean(); - - int fieldsNum = isExternalizable? 0 : DataIO.unpackInt(in); - FieldInfo[] fields = new FieldInfo[fieldsNum]; - for (int j = 0; j < fieldsNum; j++) { - fields[j] = new FieldInfo(in.readUTF(), in.readBoolean(), in.readUTF(), classForName(className)); - } - ret.add(new ClassInfo(className, fields,isEnum,isExternalizable)); - } - return new CopyOnWriteArrayList(ret); - } - - @Override - public int fixedSize() { - return -1; - } - - }; - private static final long serialVersionUID = 3181417366609199703L; - - protected final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(CC.FAIR_LOCKS); - - protected static Class classForName(String className) { - try { - final ClassLoader loader = Thread.currentThread().getContextClassLoader(); - return Class.forName(className, true,loader); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - - protected DB db; - - - public SerializerPojo(CopyOnWriteArrayList registered){ - if(registered == null) - registered = new CopyOnWriteArrayList(); - this.registered = registered; - oldSize = registered.size(); - for(int i=0;i fields = new ArrayList(); - protected final Map name2fieldInfo = new HashMap(); - protected final Map name2fieldId = new HashMap(); - protected ObjectStreamField[] objectStreamFields; - - protected final boolean isEnum; - - protected final boolean useObjectStream; - - public ClassInfo(final String name, final FieldInfo[] fields, final boolean isEnum, final boolean isExternalizable) { - this.name = name; - this.isEnum = isEnum; - this.useObjectStream = isExternalizable; - - for (FieldInfo f : fields) { - this.name2fieldId.put(f.name, this.fields.size()); - this.fields.add(f); - this.name2fieldInfo.put(f.name, f); - } - } - - - public int getFieldId(String name) { - Integer fieldId = name2fieldId.get(name); - if(fieldId != null) - return fieldId; - return -1; - } - - - public int addFieldInfo(FieldInfo field) { - name2fieldId.put(field.name, fields.size()); - name2fieldInfo.put(field.name, field); - fields.add(field); - return fields.size() - 1; - } - - public ObjectStreamField[] getObjectStreamFields() { - return objectStreamFields; - } - - public void setObjectStreamFields(ObjectStreamField[] objectStreamFields) { - this.objectStreamFields = objectStreamFields; - } - - @Override public String toString(){ - return super.toString()+ "["+name+"]"; - } - - - } - - /** - * Stores info about single field stored in MapDB. - * Roughly corresponds to 'java.io.ObjectFieldClass' - */ - protected static class FieldInfo { - protected final String name; - protected final boolean primitive; - protected final String type; - protected Class typeClass; - // Class containing this field - protected final Class clazz; - protected Field field; - - public FieldInfo(String name, boolean primitive, String type, Class clazz) { - this.name = name; - this.primitive = primitive; - this.type = type; - this.clazz = clazz; - this.typeClass = primitive?null:classForName(type); - - //init field - - Class aClazz = clazz; - - // iterate over class hierarchy, until root class - while (true) { - if(aClazz == Object.class) throw new RuntimeException("Could not set field value: "+name+" - "+clazz.toString()); - // access field directly - try { - Field f = aClazz.getDeclaredField(name); - // security manager may not be happy about this - if (!f.isAccessible()) - f.setAccessible(true); - field = f; - break; - } catch (NoSuchFieldException e) { - //field does not exists - } - // move to superclass - aClazz = aClazz.getSuperclass(); - - - } - } - - - public FieldInfo(ObjectStreamField sf, Class clazz) { - this(sf.getName(), sf.isPrimitive(), sf.getType().getName(), clazz); - } - - } - - - protected CopyOnWriteArrayList registered; - protected Map, Integer> class2classId = new HashMap, Integer>(); - protected Map> classId2class = new HashMap>(); - - - - public void registerClass(Class clazz) throws IOException { - if (containsClass(clazz)) - return; - - if(CC.PARANOID && ! (lock.isWriteLockedByCurrentThread())) - throw new AssertionError(); - - final boolean advancedSer = usesAdvancedSerialization(clazz); - ObjectStreamField[] streamFields = advancedSer? new ObjectStreamField[0]:getFields(clazz); - FieldInfo[] fields = new FieldInfo[streamFields.length]; - for (int i = 0; i < fields.length; i++) { - ObjectStreamField sf = streamFields[i]; - fields[i] = new FieldInfo(sf, clazz); - } - - ClassInfo i = new ClassInfo(clazz.getName(), fields,clazz.isEnum(), advancedSer); - class2classId.put(clazz, registered.size()); - classId2class.put(registered.size(), clazz); - registered.add(i); - - saveClassInfo(); - } - - protected boolean usesAdvancedSerialization(Class clazz) { - if(Externalizable.class.isAssignableFrom(clazz)) return true; - try { - if(clazz.getDeclaredMethod("readObject",ObjectInputStream.class)!=null) return true; - } catch (NoSuchMethodException e) { - } - try { - if(clazz.getDeclaredMethod("writeObject",ObjectOutputStream.class)!=null) return true; - } catch (NoSuchMethodException e) { - } - - - try { - if(clazz.getDeclaredMethod("writeReplace")!=null) return true; - } catch (NoSuchMethodException e) { - } - - return false; - } - - /** action performed after classInfo was modified, feel free to override */ - protected void saveClassInfo() { - - } - - protected ObjectStreamField[] getFields(Class clazz) { - ObjectStreamField[] fields = null; - ClassInfo classInfo = null; - Integer classId = class2classId.get(clazz); - if (classId != null) { - classInfo = registered.get(classId); - fields = classInfo.getObjectStreamFields(); - } - if (fields == null) { - ObjectStreamClass streamClass = ObjectStreamClass.lookup(clazz); - FastArrayList fieldsList = new FastArrayList(); - while (streamClass != null) { - for (ObjectStreamField f : streamClass.getFields()) { - fieldsList.add(f); - } - clazz = clazz.getSuperclass(); - streamClass = ObjectStreamClass.lookup(clazz); - } - fields = new ObjectStreamField[fieldsList - .size]; - System.arraycopy(fieldsList.data, 0, fields, 0, fields.length); - if(classInfo != null) - classInfo.setObjectStreamFields(fields); - } - return fields; - } - - protected void assertClassSerializable(Class clazz) throws NotSerializableException, InvalidClassException { - if(containsClass(clazz)) - return; - - if (!Serializable.class.isAssignableFrom(clazz)) - throw new NotSerializableException(clazz.getName()); - - } - - - public Object getFieldValue(FieldInfo fieldInfo, Object object) { - - if(fieldInfo.field==null){ - throw new NoSuchFieldError(object.getClass() + "." + fieldInfo.name); - } - - - try { - return fieldInfo.field.get(object); - } catch (IllegalAccessException e) { - throw new RuntimeException("Could not get value from field", e); - } - } - - - - public void setFieldValue(FieldInfo fieldInfo, Object object, Object value) { - if(fieldInfo.field==null) - throw new NoSuchFieldError(object.getClass() + "." + fieldInfo.name); - - try{ - fieldInfo.field.set(object, value); - } catch (IllegalAccessException e) { - throw new RuntimeException("Could not set field value: ",e); - } - - } - - public boolean containsClass(Class clazz) { - return (class2classId.get(clazz) != null); - } - - public int getClassId(Class clazz) { - Integer classId = class2classId.get(clazz); - if(classId != null) { - return classId; - } - throw new AssertionError("Class is not registered: " + clazz); - } - - @Override - protected Engine getEngine() { - return db.getEngine(); - } - - @Override - protected void serializeUnknownObject(DataOutput out, Object obj, FastArrayList objectStack) throws IOException { - if(db!=null){ - //check for named objects - String name = db.getNameForObject(obj); - if(name!=null){ - out.write(Header.NAMED); - out.writeUTF(name); - //TODO object stack here? - return; - } - } - out.write(Header.POJO); - lock.writeLock().lock(); //TODO write lock is not necessary over entire method - try{ - Class clazz = obj.getClass(); - if( !clazz.isEnum() && clazz.getSuperclass()!=null && clazz.getSuperclass().isEnum()) - clazz = clazz.getSuperclass(); - - if(clazz != Object.class) - assertClassSerializable(clazz); - - registerClass(clazz); - - //write class header - int classId = getClassId(clazz); - DataIO.packInt(out, classId); - ClassInfo classInfo = registered.get(classId); - - if(classInfo.useObjectStream){ - ObjectOutputStream2 out2 = new ObjectOutputStream2((OutputStream) out); - out2.writeObject(obj); - return; - } - - - if(classInfo.isEnum) { - int ordinal = ((Enum)obj).ordinal(); - DataIO.packInt(out, ordinal); - } - - ObjectStreamField[] fields = getFields(clazz); - DataIO.packInt(out, fields.length); - - for (ObjectStreamField f : fields) { - //write field ID - int fieldId = classInfo.getFieldId(f.getName()); - if (fieldId == -1) { - //field does not exists in class definition stored in db, - //probably new field was added so add field descriptor - fieldId = classInfo.addFieldInfo(new FieldInfo(f, clazz)); - saveClassInfo(); - } - DataIO.packInt(out, fieldId); - //and write value - Object fieldValue = getFieldValue(classInfo.fields.get(fieldId), obj); - serialize(out, fieldValue, objectStack); - } - }finally{ - lock.writeLock().unlock(); - } - } - - - @Override - protected Object deserializeUnknownHeader(DataInput in, int head, FastArrayList objectStack) throws IOException { - if(head == Header.NAMED){ - String name = in.readUTF(); - Object o = db.get(name); - if(o==null) throw new AssertionError("Named object was not found: "+name); - objectStack.add(o); - return o; - } - - if(head!= Header.POJO) throw new AssertionError(); - - lock.readLock().lock(); - //read class header - try { - int classId = DataIO.unpackInt(in); - ClassInfo classInfo = registered.get(classId); - - Class clazz = classId2class.get(classId); - if(clazz == null) - clazz = classForName(classInfo.name); - assertClassSerializable(clazz); - - Object o; - - if(classInfo.useObjectStream){ - ObjectInputStream2 in2 = new ObjectInputStream2(in); - o = in2.readObject(); - }else if(classInfo.isEnum) { - int ordinal = DataIO.unpackInt(in); - o = clazz.getEnumConstants()[ordinal]; - } - else{ - o = createInstanceSkippinkConstructor(clazz); - } - - objectStack.add(o); - - if(!classInfo.useObjectStream){ - int fieldCount = DataIO.unpackInt(in); - for (int i = 0; i < fieldCount; i++) { - int fieldId = DataIO.unpackInt(in); - FieldInfo f = classInfo.fields.get(fieldId); - Object fieldValue = deserialize(in, objectStack); - setFieldValue(f, o, fieldValue); - } - } - return o; - } catch (Exception e) { - throw new RuntimeException("Could not instantiate class", e); - }finally { - lock.readLock().unlock(); - } - } - - - static protected Method sunConstructor = null; - static protected Object sunReflFac = null; - static protected Method androidConstructor = null; - static private Method androidConstructorGinger = null; - static private int constructorId; - - static{ - try{ - Class clazz = classForName("sun.reflect.ReflectionFactory"); - if(clazz!=null){ - Method getReflectionFactory = clazz.getMethod("getReflectionFactory"); - sunReflFac = getReflectionFactory.invoke(null); - sunConstructor = clazz.getMethod("newConstructorForSerialization", - java.lang.Class.class, java.lang.reflect.Constructor.class); - } - }catch(Exception e){ - //ignore - } - - if(sunConstructor == null)try{ - //try android way - Method newInstance = ObjectInputStream.class.getDeclaredMethod("newInstance", Class.class, Class.class); - newInstance.setAccessible(true); - androidConstructor = newInstance; - - }catch(Exception e){ - //ignore - } - - //this method was taken from - //http://dexmaker.googlecode.com/git-history/5a7820356e68a977711afc854d6cd71296c56391/src/mockito/java/com/google/dexmaker/mockito/UnsafeAllocator.java - //Copyright (C) 2012 The Android Open Source Project, licenced under Apache 2 license - if(sunConstructor == null && androidConstructor == null)try{ - //try android post ginger way - Method getConstructorId = ObjectStreamClass.class.getDeclaredMethod("getConstructorId", Class.class); - getConstructorId.setAccessible(true); - constructorId = (Integer) getConstructorId.invoke(null, Object.class); - - Method newInstance = ObjectStreamClass.class.getDeclaredMethod("newInstance", Class.class, int.class); - newInstance.setAccessible(true); - androidConstructorGinger = newInstance; - - }catch(Exception e){ - //ignore - } - } - - - protected static Map, Constructor> class2constuctor = new ConcurrentHashMap, Constructor>(); - - /** - * For pojo serialization we need to instantiate class without invoking its constructor. - * There are two ways to do it: - *

- * Using proprietary API on Oracle JDK and OpenJDK - * sun.reflect.ReflectionFactory.getReflectionFactory().newConstructorForSerialization() - * more at http://www.javaspecialists.eu/archive/Issue175.html - *

- * Using 'ObjectInputStream.newInstance' on Android - * http://stackoverflow.com/a/3448384 - *

- * If non of these works we fallback into usual reflection which requires an no-arg constructor - */ - @SuppressWarnings("restriction") - protected T createInstanceSkippinkConstructor(Class clazz) - throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { - - if(sunConstructor !=null){ - //Sun specific way - Constructor intConstr = class2constuctor.get(clazz); - - if (intConstr == null) { - Constructor objDef = Object.class.getDeclaredConstructor(); - intConstr = (Constructor) sunConstructor.invoke(sunReflFac, clazz, objDef); - class2constuctor.put(clazz, intConstr); - } - - return (T)intConstr.newInstance(); - }else if(androidConstructor!=null){ - //android (harmony) specific way - return (T)androidConstructor.invoke(null, clazz, Object.class); - }else if(androidConstructorGinger!=null){ - //android (post ginger) specific way - return (T)androidConstructorGinger.invoke(null, clazz, constructorId); - } - else{ - //try usual generic stuff which does not skip constructor - Constructor c = class2constuctor.get(clazz); - if(c==null){ - c =clazz.getConstructor(); - if(!c.isAccessible()) c.setAccessible(true); - class2constuctor.put(clazz,c); - } - return (T)c.newInstance(); - } - } - - - - protected final class ObjectOutputStream2 extends ObjectOutputStream{ - - - protected ObjectOutputStream2(OutputStream out) throws IOException, SecurityException { - super(out); - } - - @Override - protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException { - Integer classId = class2classId.get(desc.forClass()); - if(classId ==null){ - registerClass(desc.forClass()); - classId = class2classId.get(desc.forClass()); - } - DataIO.packInt(this,classId); - } - } - - protected final class ObjectInputStream2 extends ObjectInputStream{ - - protected ObjectInputStream2(DataInput in) throws IOException, SecurityException { - super(new DataIO.DataInputToStream(in)); - } - - @Override - protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { - Integer classId = DataIO.unpackInt(this); - Class clazz = classId2class.get(classId); - return ObjectStreamClass.lookup(clazz); - } - - @Override - protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - Class clazz = Class.forName(desc.getName(), false, loader); - if (clazz != null) - return clazz; - return super.resolveClass(desc); - } - } - - protected int oldSize; - - public boolean hasUnsavedChanges(){ - return oldSize!=registered.size(); - } - public void save(Engine e){ - //TODO thread safe? - e.update(Engine.CLASS_INFO_RECID, registered, SerializerPojo.serializer); - oldSize = registered.size(); - } - - protected CopyOnWriteArrayList serializationTransformsSerialize; - protected CopyOnWriteArrayList serializationTransformsDeserialize; - - /** - * Add interceptor which may modify all deserialized/serialized objects - * - * @param beforeSerialization transform called on all object before they are serialized - * @param afterDeserialization transform called on all object after they are serialized - */ - public void serializerTransformAdd(Fun.Function1 beforeSerialization, Fun.Function1 afterDeserialization ){ - lock.writeLock().lock(); //TODO ensure thread safety - try { - - if (serializationTransformsSerialize == null) { - serializationTransformsSerialize = new CopyOnWriteArrayList(); - serializationTransformsDeserialize = new CopyOnWriteArrayList(); - } - - serializationTransformsSerialize.add(beforeSerialization); - serializationTransformsDeserialize.add(afterDeserialization); - }finally { - lock.writeLock().unlock(); - } - } - - - /** - * Removes interceptor which may modify all deserialized/serialized objects - * - * @param beforeSerialization transform called on all object before they are serialized - * @param afterDeserialization transform called on all object after they are serialized - */ - - public void serializerTransformRemove(Fun.Function1 beforeSerialization, Fun.Function1 afterDeserialization ){ - lock.writeLock().lock(); //TODO ensure thread safety - try { - - if(serializationTransformsSerialize ==null){ - return; - } - serializationTransformsSerialize.remove(beforeSerialization); - serializationTransformsDeserialize.remove(afterDeserialization); - }finally { - lock.writeLock().unlock(); - } - } - - - @Override - public void serialize(DataOutput out, Object obj) throws IOException { - if(serializationTransformsSerialize!=null){ - for(Fun.Function1 f:serializationTransformsSerialize){ - obj = f.run(obj); - } - } - super.serialize(out,obj); - } - - @Override - public Object deserialize(DataInput is, int capacity) throws IOException { - Object obj = super.deserialize(is, capacity); - - if(serializationTransformsDeserialize!=null){ - for(Fun.Function1 f:serializationTransformsDeserialize){ - obj = f.run(obj); - } - } - - return obj; - } -} \ No newline at end of file diff --git a/src/main/java/org/mapdb/Store.java b/src/main/java/org/mapdb/Store.java deleted file mode 100644 index 7f82889ca..000000000 --- a/src/main/java/org/mapdb/Store.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ -package org.mapdb; - -import java.io.DataInput; -import java.io.IOError; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Queue; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.logging.Logger; -import java.util.zip.CRC32; - -/** - * Low level record store. - */ -public abstract class Store implements Engine{ - - protected static final Logger LOG = Logger.getLogger(Store.class.getName()); - - protected final String fileName; - protected final boolean checksum; - protected final boolean compress; - protected final boolean encrypt; - protected final byte[] password; - protected final EncryptionXTEA encryptionXTEA; - - protected final static int CHECKSUM_FLAG_MASK = 1; - protected final static int COMPRESS_FLAG_MASK = 1<<2; - protected final static int ENCRYPT_FLAG_MASK = 1<<3; - - - protected static final int SLICE_SIZE = 1<< CC.VOLUME_SLICE_SHIFT; - - protected static final int SLICE_SIZE_MOD_MASK = SLICE_SIZE -1; - protected final Fun.Function1 volumeFactory; - - /** default serializer used for persistence. Handles POJO and other stuff which requires write-able access to Engine */ - protected SerializerPojo serializerPojo; - - - - protected final ThreadLocal LZF; - - protected Store(String fileName, Fun.Function1 volumeFactory, boolean checksum, boolean compress, byte[] password) { - this.fileName = fileName; - this.volumeFactory = volumeFactory; - structuralLock = new ReentrantLock(CC.FAIR_LOCKS); - newRecidLock = new ReentrantReadWriteLock(CC.FAIR_LOCKS); - locks = new ReentrantReadWriteLock[CC.CONCURRENCY]; - for(int i=0;i< locks.length;i++){ - locks[i] = new ReentrantReadWriteLock(CC.FAIR_LOCKS); - } - - this.checksum = checksum; - this.compress = compress; - this.encrypt = password!=null; - this.password = password; - this.encryptionXTEA = !encrypt?null:new EncryptionXTEA(password); - - this.LZF = !compress?null:new ThreadLocal() { - @Override - protected CompressLZF initialValue() { - return new CompressLZF(); - } - }; - } - - public abstract long getMaxRecid(); - public abstract ByteBuffer getRaw(long recid); - public abstract Iterator getFreeRecids(); - public abstract void updateRaw(long recid, ByteBuffer data); - - /** returns maximal store size or `0` if there is no limit */ - public abstract long getSizeLimit(); - - /** returns current size occupied by physical store (does not include index). It means file allocated by physical file */ - public abstract long getCurrSize(); - - /** returns free size in physical store (does not include index). */ - public abstract long getFreeSize(); - - /** get some statistics about store. This may require traversing entire store, so it can take some time.*/ - public abstract String calculateStatistics(); - - public void printStatistics(){ - System.out.println(calculateStatistics()); - } - - protected Lock serializerPojoInitLock = new ReentrantLock(CC.FAIR_LOCKS); - - /** - * @return default serializer used in this DB, it handles POJO and other stuff. - */ - public SerializerPojo getSerializerPojo() { - final Lock pojoLock = serializerPojoInitLock; - if(pojoLock!=null) { - pojoLock.lock(); - try{ - if(serializerPojo==null){ - final CopyOnWriteArrayList classInfos = get(Engine.CLASS_INFO_RECID, SerializerPojo.serializer); - serializerPojo = new SerializerPojo(classInfos); - serializerPojoInitLock = null; - } - }finally{ - pojoLock.unlock(); - } - - } - return serializerPojo; - } - - - protected final ReentrantLock structuralLock; - protected final ReentrantReadWriteLock newRecidLock; - protected final ReentrantReadWriteLock[] locks; - - - protected void lockAllWrite() { - newRecidLock.writeLock().lock(); - for(ReentrantReadWriteLock l: locks) { - l.writeLock().lock(); - } - structuralLock.lock(); - } - - protected void unlockAllWrite() { - structuralLock.unlock(); - for(ReentrantReadWriteLock l: locks) { - l.writeLock().unlock(); - } - newRecidLock.writeLock().unlock(); - } - - - - protected final Queue recycledDataOuts = new ArrayBlockingQueue(128); - - - protected DataIO.DataOutputByteArray serialize(A value, Serializer serializer){ - try { - DataIO.DataOutputByteArray out = newDataOut2(); - - serializer.serialize(out,value); - - if(out.pos>0){ - - if(compress){ - DataIO.DataOutputByteArray tmp = newDataOut2(); - tmp.ensureAvail(out.pos+40); - final CompressLZF lzf = LZF.get(); - int newLen; - try{ - newLen = lzf.compress(out.buf,out.pos,tmp.buf,0); - }catch(IndexOutOfBoundsException e){ - newLen=0; //larger after compression - } - if(newLen>=out.pos) newLen= 0; //larger after compression - - if(newLen==0){ - recycledDataOuts.offer(tmp); - //compression had no effect, so just write zero at beginning and move array by 1 - out.ensureAvail(out.pos+1); - System.arraycopy(out.buf,0,out.buf,1,out.pos); - out.pos+=1; - out.buf[0] = 0; - }else{ - //compression had effect, so write decompressed size and compressed array - final int decompSize = out.pos; - out.pos=0; - DataIO.packInt(out,decompSize); - out.write(tmp.buf,0,newLen); - recycledDataOuts.offer(tmp); - } - - } - - - if(encrypt){ - int size = out.pos; - //round size to 16 - if(size%EncryptionXTEA.ALIGN!=0) - size += EncryptionXTEA.ALIGN - size%EncryptionXTEA.ALIGN; - final int sizeDif=size-out.pos; - //encrypt - out.ensureAvail(sizeDif+1); - encryptionXTEA.encrypt(out.buf,0,size); - //and write diff from 16 - out.pos = size; - out.writeByte(sizeDif); - } - - if(checksum){ - CRC32 crc = new CRC32(); - crc.update(out.buf,0,out.pos); - out.writeInt((int)crc.getValue()); - } - - if(CC.PARANOID)try{ - //check that array is the same after deserialization - DataInput inp = new DataIO.DataInputByteArray(Arrays.copyOf(out.buf,out.pos)); - byte[] decompress = deserialize(Serializer.BYTE_ARRAY_NOSIZE,out.pos,inp); - - DataIO.DataOutputByteArray expected = newDataOut2(); - serializer.serialize(expected,value); - - byte[] expected2 = Arrays.copyOf(expected.buf, expected.pos); - //check arrays equals - if(CC.PARANOID && ! (Arrays.equals(expected2,decompress))) - throw new AssertionError(); - - - }catch(Exception e){ - throw new RuntimeException(e); - } - } - return out; - } catch (IOException e) { - throw new IOError(e); - } - - } - - protected DataIO.DataOutputByteArray newDataOut2() { - DataIO.DataOutputByteArray tmp = recycledDataOuts.poll(); - if(tmp==null) tmp = new DataIO.DataOutputByteArray(); - else tmp.pos=0; - return tmp; - } - - - protected A deserialize(Serializer serializer, int size, DataInput input) throws IOException { - DataIO.DataInputInternal di = (DataIO.DataInputInternal) input; - if(size>0){ - if(checksum){ - //last two digits is checksum - size -= 4; - - //read data into tmp buffer - DataIO.DataOutputByteArray tmp = newDataOut2(); - tmp.ensureAvail(size); - int oldPos = di.getPos(); - di.readFully(tmp.buf, 0, size); - final int checkExpected = di.readInt(); - di.setPos(oldPos); - //calculate checksums - CRC32 crc = new CRC32(); - crc.update(tmp.buf, 0, size); - recycledDataOuts.offer(tmp); - int check = (int) crc.getValue(); - if(check!=checkExpected) - throw new IOException("Checksum does not match, data broken"); - } - - if(encrypt){ - DataIO.DataOutputByteArray tmp = newDataOut2(); - size-=1; - tmp.ensureAvail(size); - di.readFully(tmp.buf, 0, size); - encryptionXTEA.decrypt(tmp.buf, 0, size); - int cut = di.readUnsignedByte(); //length dif from 16bytes - di = new DataIO.DataInputByteArray(tmp.buf); - size -= cut; - } - - if(compress) { - //final int origPos = di.pos; - int decompSize = DataIO.unpackInt(di); - if(decompSize==0){ - size-=1; - //rest of `di` is uncompressed data - }else{ - DataIO.DataOutputByteArray out = newDataOut2(); - out.ensureAvail(decompSize); - CompressLZF lzf = LZF.get(); - //TODO copy to heap if Volume is not mapped - //argument is not needed; unpackedSize= size-(di.pos-origPos), - byte[] b = di.internalByteArray(); - if(b!=null) { - lzf.expand(b, di.getPos(), out.buf, 0, decompSize); - }else{ - ByteBuffer bb = di.internalByteBuffer(); - if(bb!=null) { - lzf.expand(bb, di.getPos(), out.buf, 0, decompSize); - }else{ - lzf.expand(di,out.buf, 0, decompSize); - } - } - di = new DataIO.DataInputByteArray(out.buf); - size = decompSize; - } - } - - } - - int start = di.getPos(); - - A ret = serializer.deserialize(di,size); - if(size+start>di.getPos()) - throw new AssertionError("data were not fully read, check your serializer "); - if(size+start>> 32)); - h ^= (h >>> 20) ^ (h >>> 12); - h ^= (h >>> 7) ^ (h >>> 4); - return h & LOCK_MASK; - } - - @Override - public boolean canSnapshot() { - return false; - } - - @Override - public Engine snapshot() throws UnsupportedOperationException { - throw new UnsupportedOperationException("Snapshots are not supported"); - } - - - -} diff --git a/src/main/java/org/mapdb/StoreAppend.java b/src/main/java/org/mapdb/StoreAppend.java deleted file mode 100644 index ea7fe31be..000000000 --- a/src/main/java/org/mapdb/StoreAppend.java +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.io.DataInput; -import java.io.File; -import java.io.IOError; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Iterator; -import java.util.Random; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.concurrent.locks.Lock; - -/** - * Append only store. Uses different file format than Direct and WAL store - * - */ -public class StoreAppend extends Store{ - - /** header at beginning of each file */ - protected static final long HEADER = 1239900952130003033L; - - /** index value has two parts, first is file number, second is offset in file, this is how many bites file offset occupies */ - protected static final int FILE_SHIFT = 24; - - /** mask used to get file offset from index val*/ - protected static final long FILE_MASK = 0xFFFFFF; - - protected static final int MAX_FILE_SIZE_SHIFT = CC.VOLUME_SLICE_SHIFT + 6; //TODO shift + 6 !! - - /** add to size before writing it to file */ - protected static final long SIZEP = 2; - /** add to recid before writing it to file */ - protected static final long RECIDP = 3; - /** at place of recid indicates uncommited transaction, an end of append log */ - protected static final long END = 1-RECIDP; - /** at place of recid indicates commited transaction, just ignore this value and continue */ - protected static final long SKIP = 2-RECIDP; - - protected final boolean useRandomAccessFile; - protected final boolean readOnly; - protected final boolean syncOnCommit; - protected final boolean deleteFilesAfterClose; - /** transactions enabled*/ - protected final boolean tx; - - /** true after file was closed */ - protected volatile boolean closed = false; - /** true after file was modified */ - protected volatile boolean modified = false; - - - /** contains opened files, key is file number*/ - protected final LongConcurrentHashMap volumes = new LongConcurrentHashMap(); - - /** last uses file, currently writing into */ - protected Volume currVolume; - /** last used position, currently writing into */ - protected long currPos; - /** last file number, currently writing into */ - protected long currFileNum; - /** maximal recid */ - protected long maxRecid; - - /** file position on last commit, used for rollback */ - protected long rollbackCurrPos; - /** file number on last commit, used for rollback */ - protected long rollbackCurrFileNum; - /** maximial recid on last commit, used for rollback */ - protected long rollbackMaxRecid; - - /** index table which maps recid into position in index log */ - protected Volume index = new Volume.MemoryVol(false,0, MAX_FILE_SIZE_SHIFT); //TODO option to keep index off-heap or in file - /** same as `index`, but stores uncommited modifications made in this transaction*/ - protected final LongMap indexInTx; - - - - - public StoreAppend(final String fileName, Fun.Function1 volumeFactory, - final boolean useRandomAccessFile, final boolean readOnly, - final boolean transactionDisabled, final boolean deleteFilesAfterClose, final boolean syncOnCommitDisabled, - boolean checksum, boolean compress, byte[] password) { - super(fileName, volumeFactory, checksum, compress, password); - - this.useRandomAccessFile = useRandomAccessFile; - this.readOnly = readOnly; - this.deleteFilesAfterClose = deleteFilesAfterClose; - this.syncOnCommit = !syncOnCommitDisabled; - this.tx = !transactionDisabled; - indexInTx = tx?new LongConcurrentHashMap() : null; - - final File parent = new File(fileName).getAbsoluteFile().getParentFile(); - if(!parent.exists() || !parent.isDirectory()) - throw new IllegalArgumentException("Parent dir does not exist: "+fileName); - - //list all matching files and sort them by number - final SortedSet> sortedFiles = new TreeSet>(); - final String prefix = new File(fileName).getName(); - for(File f:parent.listFiles()){ - String name= f.getName(); - if(!name.startsWith(prefix) || name.length()<=prefix.length()+1) continue; - String number = name.substring(prefix.length()+1, name.length()); - if(!number.matches("^[0-9]+$")) continue; - sortedFiles.add(new Fun.Pair(Long.valueOf(number),f)); - } - - - if(sortedFiles.isEmpty()){ - //no files, create empty store - Volume zero = Volume.volumeForFile(getFileFromNum(0),useRandomAccessFile, readOnly,0L,MAX_FILE_SIZE_SHIFT,0); - zero.ensureAvailable(Engine.LAST_RESERVED_RECID*8+8); - zero.putLong(0, HEADER); - long pos = 8; - //put reserved records as empty - for(long recid=1;recid<=LAST_RESERVED_RECID;recid++){ - pos+=zero.putPackedLong(pos, recid+RECIDP); - pos+=zero.putPackedLong(pos, 0+SIZEP); //and mark it with zero size (0==tombstone) - } - maxRecid = LAST_RESERVED_RECID; - index.ensureAvailable(LAST_RESERVED_RECID * 8 + 8); - - volumes.put(0L, zero); - - if(tx){ - rollbackCurrPos = pos; - rollbackMaxRecid = maxRecid; - rollbackCurrFileNum = 0; - zero.putUnsignedByte(pos, (int) (END+RECIDP)); - pos++; - } - - currVolume = zero; - currPos = pos; - }else{ - //some files exists, open, check header and replay index - for(Fun.Pair t:sortedFiles){ - Long num = t.a; - File f = t.b; - Volume vol = Volume.volumeForFile(f,useRandomAccessFile,readOnly, 0L, MAX_FILE_SIZE_SHIFT,0); - if(vol.isEmpty()||vol.getLong(0)!=HEADER){ - vol.sync(); - vol.close(); - Iterator vols = volumes.valuesIterator(); - while(vols.hasNext()){ - Volume next = vols.next(); - next.sync(); - next.close(); - } - throw new IOError(new IOException("File corrupted: "+f)); - } - volumes.put(num, vol); - - long pos = 8; - while(pos<=FILE_MASK){ - long recid = vol.getPackedLong(pos); - pos+=packedLongSize(recid); - recid -= RECIDP; - maxRecid = Math.max(recid,maxRecid); -// System.out.println("replay "+recid+ " - "+pos); - - if(recid==END){ - //reached end of file - currVolume = vol; - currPos = pos; - currFileNum = num; - rollbackCurrFileNum = num; - rollbackMaxRecid = maxRecid; - rollbackCurrPos = pos-1; - - - return; - }else if(recid==SKIP){ - //commit mark, so skip - continue; - }else if(recid<=0){ - Iterator vols = volumes.valuesIterator(); - while(vols.hasNext()){ - Volume next = vols.next(); - next.sync(); - next.close(); - } - throw new IOError(new IOException("File corrupted: "+f)); - } - - index.ensureAvailable(recid*8+8); - long indexVal = (num<0){ - pos+=size; - index.putLong(recid*8,indexVal); - }else{ - index.putLong(recid*8, Long.MIN_VALUE); //TODO tombstone - } - } - } - Iterator vols = volumes.valuesIterator(); - while(vols.hasNext()){ - Volume next = vols.next(); - next.sync(); - next.close(); - } - throw new IOError(new IOException("File not sealed, data possibly corrupted")); - } - } - - public StoreAppend(String fileName) { - this( fileName, - fileName==null || fileName.isEmpty()?Volume.memoryFactory():Volume.fileFactory(), - false, - false, - false, - false, - false, - false, - false, - null - ); - } - - - protected File getFileFromNum(long fileNumber){ - return new File(fileName+"."+fileNumber); - } - - protected void rollover(){ - if(currVolume.getLong(0)!=HEADER) throw new AssertionError(); - if(currPos<=FILE_MASK || readOnly) return; - //beyond usual file size, so create new file - currVolume.sync(); - currFileNum++; - currVolume = Volume.volumeForFile(getFileFromNum(currFileNum),useRandomAccessFile, readOnly,0L, MAX_FILE_SIZE_SHIFT,0); - currVolume.ensureAvailable(8); - currVolume.putLong(0,HEADER); - currPos = 8; - volumes.put(currFileNum, currVolume); - } - - - - protected long indexVal(long recid) { - if(tx){ - Long val = indexInTx.get(recid); - if(val!=null) return val; - } - return index.getLong(recid*8); - } - - protected void setIndexVal(long recid, long indexVal) { - if(tx) indexInTx.put(recid,indexVal); - else{ - index.ensureAvailable(recid*8+8); - index.putLong(recid*8,indexVal); - } - } - - @Override - public long preallocate() { - final Lock lock = locks[new Random().nextInt(locks.length)].readLock(); - lock.lock(); - - try{ - structuralLock.lock(); - - final long recid; - try{ - recid = ++maxRecid; - - modified = true; - }finally{ - structuralLock.unlock(); - } - - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - return recid; - }finally { - lock.unlock(); - } - } - - - @Override - public void preallocate(long[] recids) { - final Lock lock = locks[new Random().nextInt(locks.length)].readLock(); - lock.lock(); - - try{ - structuralLock.lock(); - try{ - for(int i = 0;i0)) - throw new AssertionError(); - } - - modified = true; - }finally{ - structuralLock.unlock(); - } - }finally { - lock.unlock(); - } - } - - @Override - public long put(A value, Serializer serializer) { - if(CC.PARANOID && ! (value!=null)) - throw new AssertionError(); - DataIO.DataOutputByteArray out = serialize(value,serializer); - - final Lock lock = locks[new Random().nextInt(locks.length)].readLock(); - lock.lock(); - - try{ - structuralLock.lock(); - - final long oldPos,recid,indexVal; - try{ - rollover(); - currVolume.ensureAvailable(currPos+6+4+out.pos); - recid = ++maxRecid; - - //write recid - currPos+=currVolume.putPackedLong(currPos, recid+RECIDP); - indexVal = (currFileNum<0)) - throw new AssertionError(); - return recid; - }finally { - lock.unlock(); - } - } - - @Override - public A get(long recid, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - final Lock lock = locks[Store.lockPos(recid)].readLock(); - lock.lock(); - try{ - return getNoLock(recid, serializer); - }catch(IOException e){ - throw new IOError(e); - }finally { - lock.unlock(); - } - } - - protected A getNoLock(long recid, Serializer serializer) throws IOException { - long indexVal = indexVal(recid); - - if(indexVal==0) return null; - Volume vol = volumes.get(indexVal>>>FILE_SHIFT); - long fileOffset = indexVal&FILE_MASK; - long size = vol.getPackedLong(fileOffset); - fileOffset+= packedLongSize(size); - size-=SIZEP; - if(size<0) return null; - if(size==0) return serializer.deserialize(new DataIO.DataInputByteArray(new byte[0]),0); - DataInput in = vol.getDataInput(fileOffset, (int) size); - - return deserialize(serializer, (int) size,in); - } - - - @Override - public void update(long recid, A value, Serializer serializer) { - if(CC.PARANOID && ! (value!=null)) - throw new AssertionError(); - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - DataIO.DataOutputByteArray out = serialize(value,serializer); - - final Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - - try{ - updateNoLock(recid, out); - }finally { - lock.unlock(); - } - recycledDataOuts.offer(out); - } - - protected void updateNoLock(long recid, DataIO.DataOutputByteArray out) { - final long indexVal, oldPos; - - structuralLock.lock(); - try{ - rollover(); - currVolume.ensureAvailable(currPos+6+4+out.pos); - //write recid - currPos+=currVolume.putPackedLong(currPos, recid+RECIDP); - indexVal = (currFileNum< boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - if(CC.PARANOID && ! (expectedOldValue!=null && newValue!=null)) - throw new AssertionError(); - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - DataIO.DataOutputByteArray out = serialize(newValue,serializer); - final Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - - boolean ret; - try{ - Object old = getNoLock(recid,serializer); - if(expectedOldValue.equals(old)){ - updateNoLock(recid,out); - ret = true; - }else{ - ret = false; - } - }catch(IOException e){ - throw new IOError(e); - }finally { - lock.unlock(); - } - recycledDataOuts.offer(out); - return ret; - } - - @Override - public void delete(long recid, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - final Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - - try{ - structuralLock.lock(); - try{ - rollover(); - currVolume.ensureAvailable(currPos+6+0); - currPos+=currVolume.putPackedLong(currPos, recid+SIZEP); - setIndexVal(recid, (currFileNum< iter=volumes.valuesIterator(); - if(!readOnly && modified){ //TODO and modified since last open - rollover(); - currVolume.putUnsignedByte(currPos, (int) (END+RECIDP)); - } - while(iter.hasNext()){ - Volume v = iter.next(); - v.sync(); - v.close(); - if(deleteFilesAfterClose) v.deleteFile(); - } - volumes.clear(); - closed = true; - } - - @Override - public boolean isClosed() { - return closed; - } - - - @Override - public void commit() { - if(!tx){ - currVolume.sync(); - return; - } - - lockAllWrite(); - try{ - - LongMap.LongMapIterator iter = indexInTx.longMapIterator(); - while(iter.moveToNext()){ - index.ensureAvailable(iter.key()*8+8); - index.putLong(iter.key()*8, iter.value()); - } - Volume rollbackCurrVolume = volumes.get(rollbackCurrFileNum); - rollbackCurrVolume.putUnsignedByte(rollbackCurrPos, (int) (SKIP+RECIDP)); - if(syncOnCommit) rollbackCurrVolume.sync(); - - indexInTx.clear(); - - rollover(); - rollbackCurrPos = currPos; - rollbackMaxRecid = maxRecid; - rollbackCurrFileNum = currFileNum; - - currVolume.putUnsignedByte(rollbackCurrPos, (int) (END+RECIDP)); - currPos++; - - if(serializerPojo!=null && serializerPojo.hasUnsavedChanges()){ - serializerPojo.save(this); - } - - }finally{ - unlockAllWrite(); - } - - } - - - @Override - public void rollback() throws UnsupportedOperationException { - if(!tx) throw new UnsupportedOperationException("Transactions are disabled"); - - lockAllWrite(); - try{ - - indexInTx.clear(); - currVolume = volumes.get(rollbackCurrFileNum); - currPos = rollbackCurrPos; - maxRecid = rollbackMaxRecid; - currFileNum = rollbackCurrFileNum; - - //TODO rollback serializerPojo? - }finally{ - unlockAllWrite(); - } - - } - - @Override - public boolean canRollback(){ - return tx; - } - - - @Override - public boolean isReadOnly() { - return readOnly; - } - - @Override - public void clearCache() { - //no cache to clear - } - - @Override - public void compact() { - if(readOnly) throw new IllegalAccessError("readonly"); - lockAllWrite(); - try{ - - if(!indexInTx.isEmpty()) throw new IllegalAccessError("uncommited changes"); - - LongHashMap ff = new LongHashMap(); - for(long recid=0;recid<=maxRecid;recid++){ - long indexVal = index.getLong(recid*8); - if(indexVal ==0)continue; - long fileNum = indexVal>>>FILE_SHIFT; - ff.put(fileNum,true); - } - - //now traverse files and delete unused - LongMap.LongMapIterator iter = volumes.longMapIterator(); - while(iter.moveToNext()){ - long fileNum = iter.key(); - if(fileNum==currFileNum || ff.get(fileNum)!=null) continue; - Volume v = iter.value(); - v.sync(); - v.close(); - v.deleteFile(); - iter.remove(); - } - }finally{ - unlockAllWrite(); - } - - } - - @Override - public long getMaxRecid() { - return maxRecid; - } - - @Override - public ByteBuffer getRaw(long recid) { - //TODO use direct BB - byte[] bb = get(recid, Serializer.BYTE_ARRAY_NOSIZE); - if(bb==null) return null; - return ByteBuffer.wrap(bb); - } - - @Override - public Iterator getFreeRecids() { - return Fun.EMPTY_ITERATOR; //TODO free recid management - } - - @Override - public void updateRaw(long recid, ByteBuffer data) { - rollover(); - byte[] b = null; - if(data!=null){ - data = data.duplicate(); - b = new byte[data.remaining()]; - data.get(b); - } - //TODO use BB without copying - update(recid, b, Serializer.BYTE_ARRAY_NOSIZE); - modified = true; - } - - @Override - public long getSizeLimit() { - return 0; - } - - @Override - public long getCurrSize() { - return currFileNum*FILE_MASK; - } - - @Override - public long getFreeSize() { - return 0; - } - - @Override - public String calculateStatistics() { - return null; - } - - - /** get number of bytes occupied by packed long */ - protected static int packedLongSize(long value) { - int ret = 1; - while ((value & ~0x7FL) != 0) { - ret++; - value >>>= 7; - } - return ret; - } - -} - - diff --git a/src/main/java/org/mapdb/StoreHeap.java b/src/main/java/org/mapdb/StoreHeap.java deleted file mode 100644 index c1b7fdbc2..000000000 --- a/src/main/java/org/mapdb/StoreHeap.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.io.Serializable; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentNavigableMap; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.Lock; - -/** - * Store which keeps all instances on heap. It does not use serialization. - */ -public class StoreHeap extends Store implements Serializable{ - - protected final static Fun.Pair TOMBSTONE = new Fun.Pair(null,null); - - protected final static Object NULL = new Object(); - private static final long serialVersionUID = 150060834534309445L; - - /** All commited records in store */ - protected final ConcurrentNavigableMap records - = new ConcurrentSkipListMap(); - - /** All not-yet commited records in store */ - protected final ConcurrentNavigableMap rollback - = new ConcurrentSkipListMap(); - - - /** Queue of deleted recids, those are reused for new records */ - protected final Queue freeRecids = new ConcurrentLinkedQueue(); - - /** Maximal returned recid, incremented if there are no free recids*/ - protected final AtomicLong maxRecid = new AtomicLong(LAST_RESERVED_RECID); - - public StoreHeap(){ - super(null, null, false,false,null); - for(long recid=1;recid<=LAST_RESERVED_RECID;recid++){ - records.put(recid, new Fun.Pair(null, (Serializer)null)); - } - } - - - - @Override - public long preallocate() { - final Lock lock = locks[new Random().nextInt(locks.length)].writeLock(); - lock.lock(); - - try{ - Long recid = freeRecids.poll(); - if(recid==null) recid = maxRecid.incrementAndGet(); - return recid; - }finally{ - lock.unlock(); - } - } - - @Override - public void preallocate(long[] recids) { - final Lock lock = locks[new Random().nextInt(locks.length)].writeLock(); - lock.lock(); - - try{ - for(int i=0;i long put(A value, Serializer serializer) { - if(value==null) value= (A) NULL; - final Lock lock = locks[new Random().nextInt(locks.length)].writeLock(); - lock.lock(); - - try{ - Long recid = freeRecids.poll(); - if(recid==null) recid = maxRecid.incrementAndGet(); - records.put(recid, new Fun.Pair(value,serializer)); - rollback.put(recid, new Fun.Pair(TOMBSTONE,serializer )); - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - return recid; - }finally{ - lock.unlock(); - } - } - - @Override - public A get(long recid, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - final Lock lock = locks[Store.lockPos(recid)].readLock(); - lock.lock(); - - try{ - //get from commited records - Fun.Pair t = records.get(recid); - if(t==null || t.a==NULL) - return null; - return (A) t.a; - }finally{ - lock.unlock(); - } - } - - @Override - public void update(long recid, A value, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - if(CC.PARANOID && ! (serializer!=null)) - throw new AssertionError(); - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - if(value==null) value= (A) NULL; - final Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - - try{ - Fun.Pair old = records.put(recid, new Fun.Pair(value,serializer)); - if(old!=null) //TODO null if record was preallocated - rollback.putIfAbsent(recid,old); - }finally{ - lock.unlock(); - } - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - if(expectedOldValue==null) expectedOldValue= (A) NULL; - if(newValue==null) newValue= (A) NULL; - final Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - - try{ - Fun.Pair old = new Fun.Pair(expectedOldValue, serializer); - boolean ret = records.replace(recid, old, new Fun.Pair(newValue, serializer)); - if(ret) rollback.putIfAbsent(recid,old); - return ret; - }finally{ - lock.unlock(); - } - } - - @Override - public void delete(long recid, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - final Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - - try{ - Fun.Pair t2 = records.remove(recid); - if(t2!=null) rollback.putIfAbsent(recid,t2); - freeRecids.add(recid); - }finally{ - lock.unlock(); - } - } - - @Override - public void close() { - lockAllWrite(); - try{ - records.clear(); - freeRecids.clear(); - rollback.clear(); - }finally{ - unlockAllWrite(); - } - } - - @Override - public boolean isClosed() { - return false; - } - - @Override - public void commit() { - lockAllWrite(); - try{ - rollback.clear(); - }finally{ - unlockAllWrite(); - } - } - - @Override - public void rollback() throws UnsupportedOperationException { - lockAllWrite(); - try{ - //put all stuff from `rollback` into `records` - for(Map.Entry e:rollback.entrySet()){ - Long recid = e.getKey(); - Fun.Pair val = e.getValue(); - if(val == TOMBSTONE) records.remove(recid); - else records.put(recid, val); - } - rollback.clear(); - }finally{ - unlockAllWrite(); - } - } - - @Override - public boolean isReadOnly() { - return false; - } - - @Override - public void clearCache() { - } - - @Override - public void compact() { - } - - @Override - public boolean canRollback(){ - return true; - } - - - @Override - public long getMaxRecid() { - return maxRecid.get(); - } - - @Override - public ByteBuffer getRaw(long recid) { - Fun.Pair t = records.get(recid); - if(t==null||t.a == null) return null; - return ByteBuffer.wrap(serialize(t.a, (Serializer) t.b).copyBytes()); - } - - @Override - public Iterator getFreeRecids() { - return Collections.unmodifiableCollection(freeRecids).iterator(); - } - - @Override - public void updateRaw(long recid, ByteBuffer data) { - throw new UnsupportedOperationException("can not put raw data into StoreHeap"); - } - - @Override - public long getSizeLimit() { - return 0; - } - - @Override - public long getCurrSize() { - return records.size(); - } - - @Override - public long getFreeSize() { - return 0; - } - - @Override - public String calculateStatistics() { - return null; - } -} diff --git a/src/main/java/org/mapdb/StoreWAL.java b/src/main/java/org/mapdb/StoreWAL.java deleted file mode 100644 index 903c288a4..000000000 --- a/src/main/java/org/mapdb/StoreWAL.java +++ /dev/null @@ -1,1233 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.io.DataInput; -import java.io.IOError; -import java.io.IOException; -import java.util.Arrays; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.Lock; -import java.util.logging.Level; -import java.util.zip.CRC32; - -/** - * Write-Ahead-Log - */ -public class StoreWAL extends StoreDirect { - - protected static final long LOG_MASK_OFFSET = 0x0000FFFFFFFFFFFFL; - - protected static final byte WAL_INDEX_LONG = 101; - protected static final byte WAL_LONGSTACK_PAGE = 102; - protected static final byte WAL_PHYS_ARRAY_ONE_LONG = 103; - - protected static final byte WAL_PHYS_ARRAY = 104; - protected static final byte WAL_SKIP_REST_OF_BLOCK = 105; - - - /** last instruction in log file */ - protected static final byte WAL_SEAL = 111; - /** added to offset 8 into log file, indicates that log was synced and closed*/ - protected static final long LOG_SEAL = 4566556446554645L; - - public static final String TRANS_LOG_FILE_EXT = ".t"; - - protected static final long[] TOMBSTONE = new long[0]; - protected static final long[] PREALLOC = new long[0]; - - protected Volume log; - - protected volatile long logSize; - - protected final LongConcurrentHashMap modified = new LongConcurrentHashMap(); - protected final LongMap longStackPages = new LongHashMap(); - protected final long[] indexVals = new long[IO_USER_START/8]; - protected final boolean[] indexValsModified = new boolean[indexVals.length]; - - protected boolean replayPending = true; - - - protected final AtomicInteger logChecksum = new AtomicInteger(); - - public StoreWAL( - String fileName, - Fun.Function1 volFac, - Fun.Function1 indexVolFac, - boolean readOnly, - boolean deleteFilesAfterClose, - int spaceReclaimMode, - boolean syncOnCommitDisabled, - long sizeLimit, - boolean checksum, - boolean compress, - byte[] password, - int sizeIncrement) { - super(fileName, volFac, indexVolFac, - readOnly, deleteFilesAfterClose, - spaceReclaimMode, syncOnCommitDisabled, sizeLimit, - checksum, compress, password, - sizeIncrement); - - this.log = volFac.run(fileName+TRANS_LOG_FILE_EXT); - - boolean allGood = false; - structuralLock.lock(); - - try{ - reloadIndexFile(); - if(verifyLogFile()){ - replayLogFile(); - } - replayPending = false; - checkHeaders(); - if(!readOnly) - logReset(); - allGood = true; - }finally{ - if(!allGood) { - //exception was thrown, try to unlock files - if (log!=null) { - log.close(); - log = null; - } - if (index!=null) { - index.close(); - index = null; - } - if (phys!=null) { - phys.close(); - phys = null; - } - } - structuralLock.unlock(); - } - } - - - public StoreWAL(String fileName) { - this( fileName, - fileName==null || fileName.isEmpty()?Volume.memoryFactory():Volume.fileFactory(), - fileName==null || fileName.isEmpty()?Volume.memoryFactory():Volume.fileFactory(), - false, - false, - CC.DEFAULT_FREE_SPACE_RECLAIM_Q, - false, - 0, - false, - false, - null, - 0 - ); - } - - @Override - protected void checkHeaders() { - if(replayPending) return; - super.checkHeaders(); - } - - protected void reloadIndexFile() { - if(CC.PARANOID && ! ( structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); - logSize = 16; - modified.clear(); - longStackPages.clear(); - indexSize = index.getLong(IO_INDEX_SIZE); - physSize = index.getLong(IO_PHYS_SIZE); - freeSize = index.getLong(IO_FREE_SIZE); - for(int i = 0;iIO_FREE_RECID) - maxUsedIoList-=8; - } - - protected void logReset() { - if(CC.PARANOID && ! ( structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); - log.truncate(16); - log.ensureAvailable(16); - log.putInt(0, HEADER); - log.putUnsignedShort(4, STORE_VERSION); - log.putUnsignedShort(6, expectedMasks()); - log.putLong(8, 0L); - logSize = 16; - } - - - @Override - public long preallocate() { - final long ioRecid; - final long logPos; - - newRecidLock.readLock().lock(); - - try{ - structuralLock.lock(); - - try{ - ioRecid = freeIoRecidTake(false); - logPos = logSize; - //now get space in log - logSize+=1+8+8; //space used for index val - log.ensureAvailable(logSize); - - }finally{ - structuralLock.unlock(); - } - final Lock lock = locks[Store.lockPos(ioRecid)].writeLock(); - lock.lock(); - - try{ - - //write data into log - walIndexVal(logPos, ioRecid, MASK_DISCARD); - modified.put(ioRecid, PREALLOC); - }finally{ - lock.unlock(); - } - }finally{ - newRecidLock.readLock().unlock(); - } - - long recid = (ioRecid-IO_USER_START)/8; - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - return recid; - } - - - @Override - public void preallocate(final long[] recids) { - long logPos; - - newRecidLock.readLock().lock(); - try{ - structuralLock.lock(); - - try{ - logPos = logSize; - for(int i=0;i0)) - throw new AssertionError(); - } - }finally{ - newRecidLock.readLock().unlock(); - } - } - - - @Override - public long put(A value, Serializer serializer) { - if(CC.PARANOID && ! (value!=null)) - throw new AssertionError(); - DataIO.DataOutputByteArray out = serialize(value, serializer); - - final long ioRecid; - final long[] physPos; - final long[] logPos; - - newRecidLock.readLock().lock(); - - try{ - structuralLock.lock(); - - try{ - ioRecid = freeIoRecidTake(false); - //first get space in phys - physPos = physAllocate(out.pos,false,false); - //now get space in log - logPos = logAllocate(physPos); - - }finally{ - structuralLock.unlock(); - } - - final Lock lock = locks[Store.lockPos(ioRecid)].writeLock(); - lock.lock(); - - try{ - //write data into log - walIndexVal((logPos[0]&LOG_MASK_OFFSET) - 1-8-8-1-8, ioRecid, physPos[0]|MASK_ARCHIVE); - walPhysArray(out, physPos, logPos); - - modified.put(ioRecid,logPos); - recycledDataOuts.offer(out); - }finally{ - lock.unlock(); - } - }finally{ - newRecidLock.readLock().unlock(); - } - - long recid = (ioRecid-IO_USER_START)/8; - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - return recid; - } - - protected void walPhysArray(DataIO.DataOutputByteArray out, long[] physPos, long[] logPos) { - //write byte[] data - int outPos = 0; - int logC = 0; - CRC32 crc32 = new CRC32(); - - for(int i=0;i>>48); - - byte header = c==0 ? WAL_PHYS_ARRAY : WAL_PHYS_ARRAY_ONE_LONG; - log.putByte(pos - 8 - 1, header); - log.putLong(pos - 8, physPos[i]); - - if(c>0){ - log.putLong(pos, physPos[i + 1]); - } - log.putData(pos+c, out.buf, outPos, size - c); - - crc32.reset(); - crc32.update(out.buf,outPos, size-c); - logC |= DataIO.longHash(pos | header | physPos[i] | (c > 0 ? physPos[i + 1] : 0) | crc32.getValue()); - - outPos +=size-c; - if(CC.PARANOID && ! (logSize>=outPos)) - throw new AssertionError(); - } - logChecksumAdd(logC); - if(CC.PARANOID && ! (outPos==out.pos)) - throw new AssertionError(); - } - - - protected void walIndexVal(long logPos, long ioRecid, long indexVal) { - if(CC.PARANOID && ! ( locks[Store.lockPos(ioRecid)].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); - if(CC.PARANOID && ! (logSize>=logPos+1+8+8)) - throw new AssertionError(); - log.putByte(logPos, WAL_INDEX_LONG); - log.putLong(logPos + 1, ioRecid); - log.putLong(logPos + 9, indexVal); - - logChecksumAdd(DataIO.longHash(logPos | WAL_INDEX_LONG | ioRecid | indexVal)); - } - - - protected long[] logAllocate(long[] physPos) { - if(CC.PARANOID && ! ( structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); - logSize+=1+8+8; //space used for index val - - long[] ret = new long[physPos.length]; - for(int i=0;i>>48; - //would overlaps Volume Block? - logSize+=1+8; //space used for WAL_PHYS_ARRAY - ret[i] = (size<<48) | logSize; - - logSize+=size; - checkLogRounding(); - } - log.ensureAvailable(logSize); - return ret; - } - - protected void checkLogRounding() { - if(CC.PARANOID && ! ( structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); - if((logSize& SLICE_SIZE_MOD_MASK)+MAX_REC_SIZE*2> SLICE_SIZE){ - log.ensureAvailable(logSize+1); - log.putByte(logSize, WAL_SKIP_REST_OF_BLOCK); - logSize += SLICE_SIZE - (logSize& SLICE_SIZE_MOD_MASK); - } - } - - - @Override - public A get(long recid, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - final long ioRecid = IO_USER_START + recid*8; - final Lock lock = locks[Store.lockPos(ioRecid)].readLock(); - lock.lock(); - - try{ - return get2(ioRecid, serializer); - }catch(IOException e){ - throw new IOError(e); - }finally{ - lock.unlock(); - } - } - - @Override - protected A get2(long ioRecid, Serializer serializer) throws IOException { - if(CC.PARANOID && ! ( locks[Store.lockPos(ioRecid)].getWriteHoldCount()==0|| - locks[Store.lockPos(ioRecid)].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); - - //check if record was modified in current transaction - long[] r = modified.get(ioRecid); - //no, read main version - if(r==null) return super.get2(ioRecid, serializer); - //check for tombstone (was deleted in current trans) - if(r==TOMBSTONE || r==PREALLOC || r.length==0) return null; - - //was modified in current transaction, so read it from trans log - if(r.length==1){ - //single record - final int size = (int) (r[0]>>>48); - DataInput in = log.getDataInput(r[0]&LOG_MASK_OFFSET, size); - return deserialize(serializer,size,in); - }else{ - //linked record - int totalSize = 0; - for(int i=0;i>>48)-c; - } - byte[] b = new byte[totalSize]; - int pos = 0; - for(int i=0;i>>48) -c; - log.getDataInput((r[i] & LOG_MASK_OFFSET) + c, size).readFully(b,pos,size); - pos+=size; - } - if(pos!=totalSize)throw new AssertionError(); - - return deserialize(serializer,totalSize, new DataIO.DataInputByteArray(b)); - } - } - - @Override - public void update(long recid, A value, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - if(CC.PARANOID && ! (value!=null)) - throw new AssertionError(); - DataIO.DataOutputByteArray out = serialize(value, serializer); - final long ioRecid = IO_USER_START + recid*8; - final Lock lock = locks[Store.lockPos(ioRecid)].writeLock(); - lock.lock(); - - try{ - final long[] physPos; - final long[] logPos; - - long indexVal = 0; - long[] linkedRecords = getLinkedRecordsFromLog(ioRecid); - if(linkedRecords==null){ - indexVal = index.getLong(ioRecid); - linkedRecords = getLinkedRecordsIndexVals(indexVal); - }else if(linkedRecords == PREALLOC){ - linkedRecords = null; - } - - structuralLock.lock(); - - try{ - - //free first record pointed from indexVal - if((indexVal>>>48)>0) - freePhysPut(indexVal,false); - - //if there are more linked records, free those as well - if(linkedRecords!=null){ - for(int i=0; i boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - if(CC.PARANOID && ! (expectedOldValue!=null && newValue!=null)) - throw new AssertionError(); - final long ioRecid = IO_USER_START + recid*8; - final Lock lock = locks[Store.lockPos(ioRecid)].writeLock(); - lock.lock(); - - DataIO.DataOutputByteArray out; - try{ - - A oldVal = get2(ioRecid,serializer); - if((oldVal == null && expectedOldValue!=null) || (oldVal!=null && !oldVal.equals(expectedOldValue))) - return false; - - out = serialize(newValue, serializer); - - final long[] physPos; - final long[] logPos; - - long indexVal = 0; - long[] linkedRecords = getLinkedRecordsFromLog(ioRecid); - if(linkedRecords==null){ - indexVal = index.getLong(ioRecid); - linkedRecords = getLinkedRecordsIndexVals(indexVal); - } - - structuralLock.lock(); - - try{ - - //free first record pointed from indexVal - if((indexVal>>>48)>0) - freePhysPut(indexVal,false); - - //if there are more linked records, free those as well - if(linkedRecords!=null){ - for(int i=0; i void delete(long recid, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - final long ioRecid = IO_USER_START + recid*8; - final Lock lock = locks[Store.lockPos(ioRecid)].writeLock(); - lock.lock(); - - try{ - final long logPos; - - long indexVal = 0; - long[] linkedRecords = getLinkedRecordsFromLog(ioRecid); - if(linkedRecords==null){ - indexVal = index.getLong(ioRecid); - if(indexVal==MASK_DISCARD) return; - linkedRecords = getLinkedRecordsIndexVals(indexVal); - } - - structuralLock.lock(); - - try{ - logPos = logSize; - checkLogRounding(); - logSize+=1+8+8; //space used for index val - log.ensureAvailable(logSize); - longStackPut(IO_FREE_RECID, ioRecid,false); - - //free first record pointed from indexVal - if((indexVal>>>48)>0) - freePhysPut(indexVal,false); - - //if there are more linked records, free those as well - if(linkedRecords!=null){ - for(int i=0; i iter = longStackPages.longMapIterator(); - while(iter.moveToNext()){ - if(CC.PARANOID && ! (iter.key()>>>48==0)) - throw new AssertionError(); - final byte[] array = iter.value(); - final long pageSize = ((array[0]&0xFF)<<8)|(array[1]&0xFF) ; - if(CC.PARANOID && ! (array.length==pageSize)) - throw new AssertionError(); - final long firstVal = (pageSize<<48)|iter.key(); - log.ensureAvailable(logSize+1+8+pageSize); - - crc |= DataIO.longHash(logSize | WAL_LONGSTACK_PAGE | firstVal); - - log.putByte(logSize, WAL_LONGSTACK_PAGE); - logSize+=1; - log.putLong(logSize, firstVal); - logSize+=8; - - //put array - CRC32 crc32 = new CRC32(); - crc32.update(array); - crc |= crc32.getValue(); - log.putData(logSize,array,0,array.length); - logSize+=array.length; - - checkLogRounding(); - } - - - for(int i=IO_FREE_RECID;i STORE_VERSION) { - throw new IOError(new IOException("New store format version, please use newer MapDB version")); - } - - if (log.getUnsignedShort(6) != expectedMasks()) - throw new IllegalArgumentException("Log file created with different features. Please check compression, checksum or encryption"); - - try { - final CRC32 crc32 = new CRC32(); - - //all good, calculate checksum - logSize = 16; - byte ins = log.getByte(logSize); - logSize += 1; - int crc = 0; - - while (ins != WAL_SEAL){ - if (ins == WAL_INDEX_LONG) { - long ioRecid = log.getLong(logSize); - logSize += 8; - long indexVal = log.getLong(logSize); - logSize += 8; - crc |= DataIO.longHash((logSize - 1 - 8 - 8) | WAL_INDEX_LONG | ioRecid | indexVal); - } else if (ins == WAL_PHYS_ARRAY) { - final long offset2 = log.getLong(logSize); - logSize += 8; - final int size = (int) (offset2 >>> 48); - - byte[] b = new byte[size]; - log.getDataInput(logSize, size).readFully(b); - - crc32.reset(); - crc32.update(b); - - crc |= DataIO.longHash(logSize | WAL_PHYS_ARRAY | offset2 | crc32.getValue()); - - logSize += size; - } else if (ins == WAL_PHYS_ARRAY_ONE_LONG) { - final long offset2 = log.getLong(logSize); - logSize += 8; - final int size = (int) (offset2 >>> 48) - 8; - - final long nextPageLink = log.getLong(logSize); - logSize += 8; - - byte[] b = new byte[size]; - log.getDataInput(logSize, size).readFully(b); - crc32.reset(); - crc32.update(b); - - crc |= DataIO.longHash((logSize) | WAL_PHYS_ARRAY_ONE_LONG | offset2 | nextPageLink | crc32.getValue()); - - logSize += size; - } else if (ins == WAL_LONGSTACK_PAGE) { - final long offset = log.getLong(logSize); - logSize += 8; - final long origLogSize = logSize; - final int size = (int) (offset >>> 48); - - crc |= DataIO.longHash(origLogSize | WAL_LONGSTACK_PAGE | offset); - - byte[] b = new byte[size]; - log.getDataInput(logSize, size).readFully(b); - crc32.reset(); - crc32.update(b); - crc |= crc32.getValue(); - - log.getDataInput(logSize, size).readFully(b); - logSize+=size; - } else if (ins == WAL_SKIP_REST_OF_BLOCK) { - logSize += SLICE_SIZE - (logSize & SLICE_SIZE_MOD_MASK); - } else { - return false; - } - - ins = log.getByte(logSize); - logSize += 1; - } - - long indexSize = log.getSixLong(logSize); - logSize += 6; - long physSize = log.getSixLong(logSize); - logSize += 6; - long freeSize = log.getSixLong(logSize); - logSize += 6; - long indexSum = log.getLong(logSize); - logSize += 8; - crc |= DataIO.longHash((logSize - 1 - 3 * 6 - 8) | indexSize | physSize | freeSize | indexSum); - - final int realCrc = log.getInt(logSize); - logSize += 4; - - logSize = 0; - if(CC.PARANOID && ! (structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); - - //checksum is broken, so disable it - return true; - } catch (IOException e) { - LOG.log(Level.INFO, "Revert corrupted Write-Ahead-Log.",e); - return false; - }catch(IOError e){ - LOG.log(Level.INFO, "Revert corrupted Write-Ahead-Log.",e); - return false; - } - } - - - - protected void replayLogFile(){ - if(CC.PARANOID && ! ( structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); - - if(readOnly && log==null) - return; //TODO how to handle log replay if we are readonly? - - logSize = 0; - - - //read headers - if(log.isEmpty() || log.getInt(0)!=HEADER || - log.getUnsignedShort(4)>STORE_VERSION || log.getLong(8) !=LOG_SEAL || - log.getUnsignedShort(6)!=expectedMasks()){ - //wrong headers, discard log - logReset(); - return; - } - - if(CC.LOG_STORE && LOG.isLoggable(Level.FINE)) - LOG.log(Level.FINE,"Replay WAL started {0}",log); - - //all good, start replay - logSize=16; - byte ins = log.getByte(logSize); - logSize+=1; - - while(ins!=WAL_SEAL){ - if(ins == WAL_INDEX_LONG){ - long ioRecid = log.getLong(logSize); - logSize+=8; - long indexVal = log.getLong(logSize); - logSize+=8; - index.ensureAvailable(ioRecid+8); - index.putLong(ioRecid, indexVal); - }else if(ins == WAL_PHYS_ARRAY||ins == WAL_LONGSTACK_PAGE || ins == WAL_PHYS_ARRAY_ONE_LONG){ - long offset = log.getLong(logSize); - logSize+=8; - final int size = (int) (offset>>>48); - offset = offset&MASK_OFFSET; - - //transfer buffer directly from log file without copying into memory - phys.ensureAvailable(offset+size); - log.transferInto(logSize,phys,offset,size); - - logSize+=size; - }else if(ins == WAL_SKIP_REST_OF_BLOCK){ - logSize += SLICE_SIZE -(logSize& SLICE_SIZE_MOD_MASK); - }else{ - throw new AssertionError("unknown trans log instruction '"+ins +"' at log offset: "+(logSize-1)); - } - - ins = log.getByte(logSize); - logSize+=1; - } - index.putLong(IO_INDEX_SIZE,log.getSixLong(logSize)); - logSize+=6; - index.putLong(IO_PHYS_SIZE,log.getSixLong(logSize)); - logSize+=6; - index.putLong(IO_FREE_SIZE,log.getSixLong(logSize)); - logSize+=6; - index.putLong(IO_INDEX_SUM,log.getLong(logSize)); - logSize+=8; - - - - //flush dbs - if(!syncOnCommitDisabled){ - phys.sync(); - index.sync(); - } - - if(CC.LOG_STORE && LOG.isLoggable(Level.FINE)) - LOG.log(Level.FINE,"Replay WAL done at size {0,number,integer}",logSize); - - logReset(); - - if(CC.PARANOID && ! ( structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); - } - - - - @Override - public void rollback() throws UnsupportedOperationException { - lockAllWrite(); - try{ - //discard trans log - logReset(); - - reloadIndexFile(); - }finally { - unlockAllWrite(); - } - } - - protected long[] getLinkedRecordsFromLog(long ioRecid){ - if(CC.PARANOID && ! ( locks[Store.lockPos(ioRecid)].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); - long[] ret0 = modified.get(ioRecid); - if(ret0==PREALLOC) return ret0; - - if(ret0!=null && ret0!=TOMBSTONE){ - long[] ret = new long[ret0.length]; - for(int i=0;i=IO_FREE_RECID && ioList>>48; - dataOffset &= MASK_OFFSET; - byte[] page = longStackGetPage(dataOffset); - - if(pos<8) throw new AssertionError(); - - final long ret = longStackGetSixLong(page, (int) pos); - - //was it only record at that page? - if(pos == 8){ - //yes, delete this page - long next = longStackGetSixLong(page,2); - long size = ((page[0]&0xFF)<<8) | (page[1]&0xFF); - if(CC.PARANOID && ! (size == page.length)) - throw new AssertionError(); - if(next !=0){ - //update index so it points to previous page - byte[] nextPage = longStackGetPage(next); //TODO this page is not modifed, but is added to LOG - long nextSize = ((nextPage[0]&0xFF)<<8) | (nextPage[1]&0xFF); - if(CC.PARANOID && ! ((nextSize-8)%6==0)) - throw new AssertionError(); - indexVals[((int) ioList/8)]=((nextSize-6)<<48)|next; - indexValsModified[((int) ioList/8)]=true; - }else{ - //zero out index - indexVals[((int) ioList/8)]=0L; - indexValsModified[((int) ioList/8)]=true; - if(maxUsedIoList==ioList){ - //max value was just deleted, so find new maxima - while(indexVals[((int) maxUsedIoList/8)]==0 && maxUsedIoList>IO_FREE_RECID){ - maxUsedIoList-=8; - } - } - } - //put space used by this page into free list - freePhysPut((size<<48) | dataOffset, true); - if(CC.PARANOID && ! (dataOffset>>>48==0)) - throw new AssertionError(); - longStackPages.remove(dataOffset); - }else{ - //no, it was not last record at this page, so just decrement the counter - pos-=6; - indexVals[((int) ioList/8)] = (pos<<48)| dataOffset; - indexValsModified[((int) ioList/8)] = true; - } - - //System.out.println("longStackTake: "+ioList+" - "+ret); - - return ret; - - } - - @Override - protected void longStackPut(long ioList, long offset, boolean recursive) { - if(CC.PARANOID && ! ( structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); - if(CC.PARANOID && ! (offset>>>48==0)) - throw new AssertionError(); - if(CC.PARANOID && ! (ioList>=IO_FREE_RECID && ioList<=IO_USER_START)) - throw new AssertionError("wrong ioList: "+ioList); - - long dataOffset = indexVals[((int) ioList/8)]; - long pos = dataOffset>>>48; - dataOffset &= MASK_OFFSET; - - if(dataOffset == 0){ //empty list? - //yes empty, create new page and fill it with values - final long listPhysid = freePhysTake((int) LONG_STACK_PREF_SIZE,true,true) &MASK_OFFSET; - if(listPhysid == 0) throw new AssertionError(); - if(CC.PARANOID && ! (listPhysid>>>48==0)) - throw new AssertionError(); - //set previous Free Index List page to zero as this is first page - //also set size of this record - byte[] page = new byte[(int) LONG_STACK_PREF_SIZE]; - page[0] = (byte) (0xFF & (page.length>>>8)); - page[1] = (byte) (0xFF & (page.length)); - longStackPutSixLong(page,2,0L); - //set record - longStackPutSixLong(page, 8, offset); - //and update index file with new page location - indexVals[((int) ioList/8)] = ( 8L << 48) | listPhysid; - indexValsModified[((int) ioList/8)] = true; - if(maxUsedIoList<=ioList) maxUsedIoList=ioList; - longStackPages.put(listPhysid,page); - }else{ - byte[] page = longStackGetPage(dataOffset); - long size = ((page[0]&0xFF)<<8)|(page[1]&0xFF); - - if(CC.PARANOID && ! (pos+6<=size)) - throw new AssertionError(); - if(pos+6==size){ //is current page full? - long newPageSize = LONG_STACK_PREF_SIZE; - if(ioList == size2ListIoRecid(LONG_STACK_PREF_SIZE)){ - //TODO double allocation fix needs more investigation - newPageSize = LONG_STACK_PREF_SIZE_ALTER; - } - //yes it is full, so we need to allocate new page and write our number there - final long listPhysid = freePhysTake((int) newPageSize,true,true) &MASK_OFFSET; - if(listPhysid == 0) throw new AssertionError(); - - byte[] newPage = new byte[(int) newPageSize]; - - //set current page size - newPage[0] = (byte) (0xFF & (newPageSize>>>8)); - newPage[1] = (byte) (0xFF & (newPageSize)); - //set location to previous page and - longStackPutSixLong(newPage,2,dataOffset&MASK_OFFSET); - - - //set the value itself - longStackPutSixLong(newPage, 8, offset); - if(CC.PARANOID && ! (listPhysid>>>48==0)) - throw new AssertionError(); - longStackPages.put(listPhysid,newPage); - - //and update index file with new page location and number of records - indexVals[((int) ioList/8)] = (8L<<48) | listPhysid; - indexValsModified[((int) ioList/8)] = true; - }else{ - //there is space on page, so just write offset and increase the counter - pos+=6; - longStackPutSixLong(page, (int) pos,offset); - indexVals[((int) ioList/8)] = (pos<<48)| dataOffset; - indexValsModified[((int) ioList/8)] = true; - } - } - } - - protected static long longStackGetSixLong(byte[] page, int pos) { - return - ((long) (page[pos + 0] & 0xff) << 40) | - ((long) (page[pos + 1] & 0xff) << 32) | - ((long) (page[pos + 2] & 0xff) << 24) | - ((long) (page[pos + 3] & 0xff) << 16) | - ((long) (page[pos + 4] & 0xff) << 8) | - ((long) (page[pos + 5] & 0xff) << 0); - } - - - protected static void longStackPutSixLong(byte[] page, int pos, long value) { - if(CC.PARANOID && ! (value>=0 && (value>>>6*8)==0)) - throw new AssertionError("value does not fit"); - page[pos + 0] = (byte) (0xff & (value >> 40)); - page[pos + 1] = (byte) (0xff & (value >> 32)); - page[pos + 2] = (byte) (0xff & (value >> 24)); - page[pos + 3] = (byte) (0xff & (value >> 16)); - page[pos + 4] = (byte) (0xff & (value >> 8)); - page[pos + 5] = (byte) (0xff & (value >> 0)); - - } - - - protected byte[] longStackGetPage(long offset) { - if(CC.PARANOID && ! (offset>=16)) - throw new AssertionError(); - if(CC.PARANOID && ! (offset>>>48==0)) - throw new AssertionError(); - - byte[] ret = longStackPages.get(offset); - if(ret==null){ - //read page size - int size = phys.getUnsignedShort(offset); - if(CC.PARANOID && ! (size>=8+6)) - throw new AssertionError(); - ret = new byte[size]; - try { - phys.getDataInput(offset,size).readFully(ret); - } catch (IOException e) { - throw new IOError(e); - } - - //and load page - longStackPages.put(offset,ret); - } - - return ret; - } - - @Override - public void close() { - if(serializerPojo!=null && serializerPojo.hasUnsavedChanges()){ - serializerPojo.save(this); - } - - lockAllWrite(); - try{ - if(log !=null){ - log.sync(); - log.close(); - if(deleteFilesAfterClose){ - log.deleteFile(); - } - } - - index.sync(); - phys.sync(); - - index.close(); - phys.close(); - if(deleteFilesAfterClose){ - index.deleteFile(); - phys.deleteFile(); - } - index = null; - phys = null; - }finally { - unlockAllWrite(); - } - } - - @Override protected void compactPreUnderLock() { - if(CC.PARANOID && ! ( structuralLock.isLocked())) - throw new AssertionError(); - if(logDirty()) - throw new IllegalAccessError("WAL not empty; commit first, than compact"); - } - - @Override protected void compactPostUnderLock() { - if(CC.PARANOID && ! ( structuralLock.isLocked())) - throw new AssertionError(); - reloadIndexFile(); - } - - - @Override - public boolean canRollback(){ - return true; - } - - protected void logChecksumAdd(int cs) { - for(;;){ - int old = logChecksum.get(); - if(logChecksum.compareAndSet(old,old|cs)) - return; - } - } - - - -} diff --git a/src/main/java/org/mapdb/TxBlock.java b/src/main/java/org/mapdb/TxBlock.java deleted file mode 100644 index 52890bbbf..000000000 --- a/src/main/java/org/mapdb/TxBlock.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -/** - * Wraps single transaction in a block - */ -public interface TxBlock { - - void tx(DB db) throws TxRollbackException; -} diff --git a/src/main/java/org/mapdb/TxEngine.java b/src/main/java/org/mapdb/TxEngine.java deleted file mode 100644 index fb97a103e..000000000 --- a/src/main/java/org/mapdb/TxEngine.java +++ /dev/null @@ -1,642 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.*; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * Naive implementation of Snapshots on top of StorageEngine. - * On update it takes old value and stores it aside. - *

- * TODO merge snapshots down with Storage for best performance - * - * @author Jan Kotek - */ -public class TxEngine extends EngineWrapper { - - protected static final Object TOMBSTONE = new Object(); - - protected final ReentrantReadWriteLock commitLock = new ReentrantReadWriteLock(CC.FAIR_LOCKS); - protected final ReentrantReadWriteLock[] locks = new ReentrantReadWriteLock[CC.CONCURRENCY]; - { - for(int i=0;i> txs = new LinkedHashSet>(); - protected ReferenceQueue txQueue = new ReferenceQueue(); - - protected final boolean fullTx; - - protected final Queue preallocRecids; - - protected final int PREALLOC_RECID_SIZE = 128; - - protected TxEngine(Engine engine, boolean fullTx) { - super(engine); - this.fullTx = fullTx; - this.preallocRecids = fullTx ? new ArrayBlockingQueue(PREALLOC_RECID_SIZE) : null; - } - - protected Long preallocRecidTake() { - if(CC.PARANOID && ! (commitLock.isWriteLockedByCurrentThread())) - throw new AssertionError(); - Long recid = preallocRecids.poll(); - if(recid!=null) return recid; - - if(uncommitedData) - throw new IllegalAccessError("uncommited data"); - - for(int i=0;i ref = txQueue.poll(); ref!=null; ref=txQueue.poll()){ - txs.remove(ref); - } - } - - @Override - public long preallocate() { - commitLock.writeLock().lock(); - try { - uncommitedData = true; - long recid = super.preallocate(); - Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - try{ - for(Reference txr:txs){ - Tx tx = txr.get(); - if(tx==null) continue; - tx.old.putIfAbsent(recid,TOMBSTONE); - } - }finally { - lock.unlock(); - } - return recid; - } finally { - commitLock.writeLock().unlock(); - } - } - - @Override - public void preallocate(long[] recids) { - commitLock.writeLock().lock(); - try { - uncommitedData = true; - super.preallocate(recids); - for(long recid:recids){ - Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - try{ - for(Reference txr:txs){ - Tx tx = txr.get(); - if(tx==null) continue; - tx.old.putIfAbsent(recid,TOMBSTONE); - } - }finally { - lock.unlock(); - } - } - } finally { - commitLock.writeLock().unlock(); - } - } - - @Override - public long put(A value, Serializer serializer) { - commitLock.readLock().lock(); - try { - uncommitedData = true; - long recid = super.put(value, serializer); - Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - try{ - for(Reference txr:txs){ - Tx tx = txr.get(); - if(tx==null) continue; - tx.old.putIfAbsent(recid,TOMBSTONE); - } - }finally { - lock.unlock(); - } - - return recid; - } finally { - commitLock.readLock().unlock(); - } - } - - - @Override - public A get(long recid, Serializer serializer) { - commitLock.readLock().lock(); - try { - return super.get(recid, serializer); - } finally { - commitLock.readLock().unlock(); - } - } - - @Override - public void update(long recid, A value, Serializer serializer) { - commitLock.readLock().lock(); - try { - uncommitedData = true; - Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - try{ - Object old = get(recid,serializer); - for(Reference txr:txs){ - Tx tx = txr.get(); - if(tx==null) continue; - tx.old.putIfAbsent(recid,old); - } - super.update(recid, value, serializer); - }finally { - lock.unlock(); - } - } finally { - commitLock.readLock().unlock(); - } - - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - commitLock.readLock().lock(); - try { - uncommitedData = true; - Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - try{ - boolean ret = super.compareAndSwap(recid, expectedOldValue, newValue, serializer); - if(ret){ - for(Reference txr:txs){ - Tx tx = txr.get(); - if(tx==null) continue; - tx.old.putIfAbsent(recid,expectedOldValue); - } - } - return ret; - }finally { - lock.unlock(); - } - } finally { - commitLock.readLock().unlock(); - } - - } - - @Override - public void delete(long recid, Serializer serializer) { - commitLock.readLock().lock(); - try { - uncommitedData = true; - Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - try{ - Object old = get(recid,serializer); - for(Reference txr:txs){ - Tx tx = txr.get(); - if(tx==null) continue; - tx.old.putIfAbsent(recid,old); - } - super.delete(recid, serializer); - }finally { - lock.unlock(); - } - } finally { - commitLock.readLock().unlock(); - } - } - - @Override - public void close() { - commitLock.writeLock().lock(); - try { - super.close(); - } finally { - commitLock.writeLock().unlock(); - } - - } - - @Override - public void commit() { - commitLock.writeLock().lock(); - try { - cleanTxQueue(); - super.commit(); - uncommitedData = false; - } finally { - commitLock.writeLock().unlock(); - } - - } - - @Override - public void rollback() { - commitLock.writeLock().lock(); - try { - cleanTxQueue(); - super.rollback(); - uncommitedData = false; - } finally { - commitLock.writeLock().unlock(); - } - - } - - protected void superCommit() { - if(CC.PARANOID && ! (commitLock.isWriteLockedByCurrentThread())) - throw new AssertionError(); - super.commit(); - } - - protected void superUpdate(long recid, A value, Serializer serializer) { - if(CC.PARANOID && ! (commitLock.isWriteLockedByCurrentThread())) - throw new AssertionError(); - super.update(recid,value,serializer); - } - - protected void superDelete(long recid, Serializer serializer) { - if(CC.PARANOID && ! (commitLock.isWriteLockedByCurrentThread())) - throw new AssertionError(); - super.delete(recid,serializer); - } - - protected A superGet(long recid, Serializer serializer) { - if(CC.PARANOID && ! (commitLock.isWriteLockedByCurrentThread())) - throw new AssertionError(); - return super.get(recid,serializer); - } - - public class Tx implements Engine{ - - protected LongConcurrentHashMap old = new LongConcurrentHashMap(); - protected LongConcurrentHashMap mod = - fullTx ? new LongConcurrentHashMap() : null; - - protected Collection usedPreallocatedRecids = - fullTx ? new ArrayList() : null; - - protected final Reference ref = new WeakReference(this,txQueue); - - protected boolean closed = false; - private Store parentEngine; - - public Tx(){ - if(CC.PARANOID && ! (commitLock.isWriteLockedByCurrentThread())) - throw new AssertionError(); - txs.add(ref); - } - - @Override - public long preallocate() { - if(!fullTx) - throw new UnsupportedOperationException("read-only"); - - commitLock.writeLock().lock(); - try{ - Long recid = preallocRecidTake(); - usedPreallocatedRecids.add(recid); - return recid; - }finally { - commitLock.writeLock().unlock(); - } - } - - @Override - public void preallocate(long[] recids) { - if(!fullTx) - throw new UnsupportedOperationException("read-only"); - - commitLock.writeLock().lock(); - try{ - for(int i=0;i long put(A value, Serializer serializer) { - if(!fullTx) - throw new UnsupportedOperationException("read-only"); - commitLock.writeLock().lock(); - try{ - Long recid = preallocRecidTake(); - usedPreallocatedRecids.add(recid); - mod.put(recid, new Fun.Pair(value,serializer)); - return recid; - }finally { - commitLock.writeLock().unlock(); - } - } - - @Override - public A get(long recid, Serializer serializer) { - commitLock.readLock().lock(); - try{ - if(closed) throw new IllegalAccessError("closed"); - Lock lock = locks[Store.lockPos(recid)].readLock(); - lock.lock(); - try{ - return getNoLock(recid, serializer); - }finally { - lock.unlock(); - } - }finally { - commitLock.readLock().unlock(); - } - } - - private A getNoLock(long recid, Serializer serializer) { - if(fullTx){ - Fun.Pair tu = mod.get(recid); - if(tu!=null){ - if(tu.a==TOMBSTONE) - return null; - return (A) tu.a; - } - } - - Object oldVal = old.get(recid); - if(oldVal!=null){ - if(oldVal==TOMBSTONE) - return null; - return (A) oldVal; - } - return TxEngine.this.get(recid, serializer); - } - - @Override - public void update(long recid, A value, Serializer serializer) { - if(!fullTx) - throw new UnsupportedOperationException("read-only"); - commitLock.readLock().lock(); - try{ - mod.put(recid, new Fun.Pair(value,serializer)); - }finally { - commitLock.readLock().unlock(); - } - } - - @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - if(!fullTx) - throw new UnsupportedOperationException("read-only"); - - commitLock.readLock().lock(); - try{ - - Lock lock = locks[Store.lockPos(recid)].writeLock(); - lock.lock(); - try{ - A oldVal = getNoLock(recid, serializer); - boolean ret = oldVal!=null && oldVal.equals(expectedOldValue); - if(ret){ - mod.put(recid,new Fun.Pair(newValue,serializer)); - } - return ret; - }finally { - lock.unlock(); - } - }finally { - commitLock.readLock().unlock(); - } - } - - @Override - public void delete(long recid, Serializer serializer) { - if(!fullTx) - throw new UnsupportedOperationException("read-only"); - - commitLock.readLock().lock(); - try{ - mod.put(recid,new Fun.Pair(TOMBSTONE,serializer)); - }finally { - commitLock.readLock().unlock(); - } - - } - - @Override - public void close() { - closed = true; - old.clear(); - ref.clear(); - } - - @Override - public boolean isClosed() { - return closed; - } - - @Override - public void commit() { - if(!fullTx) - throw new UnsupportedOperationException("read-only"); - - commitLock.writeLock().lock(); - try{ - if(closed) return; - if(uncommitedData) - throw new IllegalAccessError("uncommitted data"); - txs.remove(ref); - cleanTxQueue(); - - if(pojo.hasUnsavedChanges()) - pojo.save(this); - - //check no other TX has modified our data - LongMap.LongMapIterator oldIter = old.longMapIterator(); - while(oldIter.moveToNext()){ - long recid = oldIter.key(); - for(Reference ref2:txs){ - Tx tx = ref2.get(); - if(tx==this||tx==null) continue; - if(tx.mod.containsKey(recid)){ - close(); - throw new TxRollbackException(); - } - } - } - - LongMap.LongMapIterator iter = mod.longMapIterator(); - while(iter.moveToNext()){ - long recid = iter.key(); - if(old.containsKey(recid)){ - close(); - throw new TxRollbackException(); - } - } - - iter = mod.longMapIterator(); - while(iter.moveToNext()){ - long recid = iter.key(); - - Fun.Pair val = iter.value(); - Serializer ser = (Serializer) val.b; - Object old = superGet(recid,ser); - if(old==null) - old = TOMBSTONE; - for(Reference txr:txs){ - Tx tx = txr.get(); - if(tx==null||tx==this) continue; - tx.old.putIfAbsent(recid,old); - - } - - if(val.a==TOMBSTONE){ - superDelete(recid, ser); - }else { - superUpdate(recid, val.a, ser); - } - } - - //there are no conflicts, so update the POJO in parent - //TODO sort of hack, is it thread safe? - getWrappedEngine().getSerializerPojo().registered = pojo.registered; - superCommit(); - - close(); - }finally { - commitLock.writeLock().unlock(); - } - } - - @Override - public void rollback() throws UnsupportedOperationException { - if(!fullTx) - throw new UnsupportedOperationException("read-only"); - - commitLock.writeLock().lock(); - try{ - if(closed) return; - if(uncommitedData) - throw new IllegalAccessError("uncommitted data"); - - txs.remove(ref); - cleanTxQueue(); - - for(Long prealloc:usedPreallocatedRecids){ - TxEngine.this.superDelete(prealloc,null); - } - TxEngine.this.superCommit(); - - close(); - }finally { - commitLock.writeLock().unlock(); - } - } - - @Override - public boolean isReadOnly() { - return !fullTx; - } - - @Override - public boolean canRollback() { - return fullTx; - } - - @Override - public boolean canSnapshot() { - return false; - } - - @Override - public Engine snapshot() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - //TODO see Issue #281 - } - - @Override - public void clearCache() { - } - - @Override - public void compact() { - } - - - SerializerPojo pojo = new SerializerPojo((CopyOnWriteArrayList) TxEngine.this.getSerializerPojo().registered.clone()); - - @Override - public SerializerPojo getSerializerPojo() { - return pojo; - } - - - public Engine getWrappedEngine() { - return TxEngine.this.getWrappedEngine(); - } - - } - -} diff --git a/src/main/java/org/mapdb/TxMaker.java b/src/main/java/org/mapdb/TxMaker.java deleted file mode 100644 index 0b139491c..000000000 --- a/src/main/java/org/mapdb/TxMaker.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - - -import java.io.Closeable; - -/** - * Transaction factory - * - * @author Jan Kotek - */ -public class TxMaker implements Closeable { - - /** marker for deleted records*/ - protected static final Object DELETED = new Object(); - private final boolean txSnapshotsEnabled; - private final boolean strictDBGet; - - /** parent engine under which modifications are stored */ - protected Engine engine; - - public TxMaker(Engine engine) { - this(engine,false,false); - } - - public TxMaker(Engine engine, boolean strictDBGet, boolean txSnapshotsEnabled) { - if(engine==null) throw new IllegalArgumentException(); - if(!engine.canSnapshot()) - throw new IllegalArgumentException("Snapshot must be enabled for TxMaker"); - if(engine.isReadOnly()) - throw new IllegalArgumentException("TxMaker can not be used with read-only Engine"); - this.engine = engine; - this.strictDBGet = strictDBGet; - this.txSnapshotsEnabled = txSnapshotsEnabled; - } - - - public DB makeTx(){ - Engine snapshot = engine.snapshot(); - if(txSnapshotsEnabled) - snapshot = new TxEngine(snapshot,false); - return new DB(snapshot,strictDBGet,false); - } - - public void close() { - engine.close(); - engine = null; - } - - /** - * Executes given block withing single transaction. - * If block throws {@code TxRollbackException} execution is repeated until it does not fail. - * - * @param txBlock - */ - public void execute(TxBlock txBlock) { - for(;;){ - DB tx = makeTx(); - try{ - txBlock.tx(tx); - if(!tx.isClosed()) - tx.commit(); - return; - }catch(TxRollbackException e){ - //failed, so try again - if(!tx.isClosed()) tx.close(); - } - } - } - - /** - * Executes given block withing single transaction. - * If block throws {@code TxRollbackException} execution is repeated until it does not fail. - * - * This method returns result returned by txBlock. - * - * @param txBlock - */ - public A execute(Fun.Function1 txBlock) { - for(;;){ - DB tx = makeTx(); - try{ - A a = txBlock.run(tx); - if(!tx.isClosed()) - tx.commit(); - return a; - }catch(TxRollbackException e){ - //failed, so try again - if(!tx.isClosed()) tx.close(); - } - } - } -} diff --git a/src/main/java/org/mapdb/TxRollbackException.java b/src/main/java/org/mapdb/TxRollbackException.java deleted file mode 100644 index c62064087..000000000 --- a/src/main/java/org/mapdb/TxRollbackException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2012 Jan Kotek - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -/** - * Exception thrown when transaction is rolled back. - * @author Jan Kotek - */ -public class TxRollbackException extends RuntimeException { - - private static final long serialVersionUID = -708303624605410767L; -} diff --git a/src/main/java/org/mapdb/cli/Export.java b/src/main/java/org/mapdb/cli/Export.java new file mode 100644 index 000000000..4cd700f14 --- /dev/null +++ b/src/main/java/org/mapdb/cli/Export.java @@ -0,0 +1,10 @@ +package org.mapdb.cli; + +import org.jetbrains.annotations.NotNull; + +public class Export { + + public static void main(@NotNull String[] arrayOf) { + + } +} diff --git a/src/main/java/org/mapdb/cli/Import.java b/src/main/java/org/mapdb/cli/Import.java new file mode 100644 index 000000000..8cbac7499 --- /dev/null +++ b/src/main/java/org/mapdb/cli/Import.java @@ -0,0 +1,10 @@ +package org.mapdb.cli; + +import org.jetbrains.annotations.NotNull; + +public class Import { + + public static void main(@NotNull String[] args) { + + } +} diff --git a/src/main/java/org/mapdb/db/DB.java b/src/main/java/org/mapdb/db/DB.java new file mode 100644 index 000000000..2e13aa5e3 --- /dev/null +++ b/src/main/java/org/mapdb/db/DB.java @@ -0,0 +1,52 @@ +package org.mapdb.db; + +import org.jetbrains.annotations.NotNull; +import org.mapdb.store.HeapBufStore; +import org.mapdb.store.Store; + +import java.io.File; + +public class DB { + private final Store store; + + public DB(Store store) { + this.store = store; + } + + public Store getStore(){ + return store; + } + + public void close() { + + } + + public static class Maker { + + private final Store store; + + private Maker(Store store) { + this.store = store; + } + + @NotNull + public static Maker appendFile(@NotNull File f) { + return null; + } + + @NotNull + public DB make() { + return new DB(store); + } + + @NotNull + public static Maker heapSer() { + return new Maker(new HeapBufStore()); + } + + @NotNull + public static Maker memoryDB() { + return new Maker(new HeapBufStore()); + } + } +} diff --git a/src/main/java/org/mapdb/flat/LongBufStack.java b/src/main/java/org/mapdb/flat/LongBufStack.java new file mode 100644 index 000000000..889614d5b --- /dev/null +++ b/src/main/java/org/mapdb/flat/LongBufStack.java @@ -0,0 +1,34 @@ +package org.mapdb.flat; + +import java.nio.ByteBuffer; + +public class LongBufStack{ + + private int pos = 0; + + + //TODO LongBuffer? + private final ByteBuffer buf; + + public LongBufStack(ByteBuffer buf) { + this.buf = buf; + } + + public LongBufStack(){ + this(ByteBuffer.allocate(8*1024*1024)); + } + + public long pop(){ + if(pos==0) + return 0L; + return buf.getLong(8*(--pos)); + } + + public void push(long value){ + if(value == 0L) + throw new IllegalArgumentException(); + + buf.putLong(8*(pos++), value); + } + +} diff --git a/src/main/java/org/mapdb/io/DataIO.java b/src/main/java/org/mapdb/io/DataIO.java new file mode 100644 index 000000000..a8e960296 --- /dev/null +++ b/src/main/java/org/mapdb/io/DataIO.java @@ -0,0 +1,673 @@ +package org.mapdb.io; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.CC; +import org.mapdb.DBException; + +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.util.Arrays; + +/** + * Various IO classes and utilities.. + */ +public final class DataIO { + + private DataIO(){} + + /** + * Unpack int value from the input stream. + * + * @param in The input stream. + * @return The long value. + *a + * @throws java.io.IOException in case of IO error + */ + static public int unpackInt(DataInput2 in){ + int ret = 0; + byte v; + do{ + v = in.readByte(); + ret = (ret<<7 ) | (v & 0x7F); + }while((v&0x80)==0); + + return ret; + } + + /** + * Unpack int value from the input stream. + * + * @param in The input stream. + * @return The long value. + *a + * @throws java.io.IOException in case of IO error + */ + static public int unpackInt(DataInput in) throws IOException { + int ret = 0; + byte v; + do{ + v = in.readByte(); + ret = (ret<<7 ) | (v & 0x7F); + }while((v&0x80)==0); + + return ret; + } + + /** + * Unpack long value from the input stream. + * + * @param in The input stream. + * @return The long value. + * + * @throws java.io.IOException in case of IO error + */ + static public long unpackLong(DataInput2 in){ + long ret = 0; + byte v; + do{ + v = in.readByte(); + ret = (ret<<7 ) | (v & 0x7F); + }while((v&0x80)==0); + + return ret; + } + + static public long unpackLong(DataInput in) throws IOException { + long ret = 0; + byte v; + do{ + v = in.readByte(); + ret = (ret<<7 ) | (v & 0x7F); + }while((v&0x80)==0); + + return ret; + } + + + /** + * Unpack int value from the input stream. + * + * @param in The input stream. + * @return The long value. + * + * @throws java.io.IOException in case of IO error + */ + static public int unpackInt(InputStream in) throws IOException { + int ret = 0; + int v; + do{ + v = in.read(); + if(v==-1) + throw new EOFException(); + ret = (ret<<7 ) | (v & 0x7F); + }while((v&0x80)==0); + + return ret; + } + + + /** + * Unpack long value from the input stream. + * + * @param in The input stream. + * @return The long value. + * + * @throws java.io.IOException in case of IO error + */ + static public long unpackLong(InputStream in) throws IOException { + long ret = 0; + int v; + do{ + v = in.read(); + if(v==-1) + throw new EOFException(); + ret = (ret<<7 ) | (v & 0x7F); + }while((v&0x80)==0); + + return ret; + } + + /** + * Pack long into output. + * It will occupy 1-10 bytes depending on value (lower values occupy smaller space) + * + * @param out DataOutput to put value into + * @param value to be serialized, must be non-negative + * + * @throws java.io.IOException in case of IO error + */ + static public void packLong(DataOutput out, long value) throws IOException { + //$DELAY$ + int shift = 63-Long.numberOfLeadingZeros(value); + shift -= shift%7; // round down to nearest multiple of 7 + while(shift!=0){ + out.writeByte((byte) ((value>>>shift) & 0x7F) ); + //$DELAY$ + shift-=7; + } + out.writeByte((byte) ((value & 0x7F)|0x80)); + } + + + /** + * Pack long into output. + * It will occupy 1-10 bytes depending on value (lower values occupy smaller space) + * + * @param out OutputStream to put value into + * @param value to be serialized, must be non-negative + * + * @throws java.io.IOException in case of IO error + */ + static public void packLong(OutputStream out, long value) throws IOException { + //$DELAY$ + int shift = 63-Long.numberOfLeadingZeros(value); + shift -= shift%7; // round down to nearest multiple of 7 + while(shift!=0){ + out.write((int) ((value>>>shift) & 0x7F)); + //$DELAY$ + shift-=7; + } + out.write((int) ((value & 0x7F)|0x80)); + } + + /** + * Calculate how much bytes packed long consumes. + * + * @param value to calculate + * @return number of bytes used in packed form + */ + public static int packLongSize(long value) { + int shift = 63-Long.numberOfLeadingZeros(value); + shift -= shift%7; // round down to nearest multiple of 7 + int ret = 1; + while(shift!=0){ + //PERF remove cycle, just count zeroes + shift-=7; + ret++; + } + return ret; + } + + + /** + * Unpack RECID value from the input stream with 3 bit checksum. + * + * @param in The input stream. + * @return The long value. + * @throws java.io.IOException in case of IO error + */ + static public long unpackRecid(DataInput2 in){ + long val = in.readPackedLong(); + val = DataIO.parity1Get(val); + return val >>> 1; + } + + + /** + * Pack RECID into output stream with 3 bit checksum. + * It will occupy 1-10 bytes depending on value (lower values occupy smaller space) + * + * @param out String to put value into + * @param value to be serialized, must be non-negative + * @throws java.io.IOException in case of IO error + */ + static public void packRecid(DataOutput2 out, long value){ + value = DataIO.parity1Set(value<<1); + out.writePackedLong(value); + } + + + /** + * Pack int into an output stream. + * It will occupy 1-5 bytes depending on value (lower values occupy smaller space) + * + * @param out DataOutput to put value into + * @param value to be serialized, must be non-negative + * @throws java.io.IOException in case of IO error + */ + + static public void packInt(DataOutput out, int value) throws IOException { + // Optimize for the common case where value is small. This is particular important where our caller + // is SerializerBase.SER_STRING.serialize because most chars will be ASCII characters and hence in this range. + // credit Max Bolingbroke https://github.com/jankotek/MapDB/pull/489 + + int shift = (value & ~0x7F); //reuse variable + if (shift != 0) { + //$DELAY$ + shift = 31-Integer.numberOfLeadingZeros(value); + shift -= shift%7; // round down to nearest multiple of 7 + while(shift!=0){ + out.writeByte((byte) ((value>>>shift) & 0x7F)); + //$DELAY$ + shift-=7; + } + } + //$DELAY$ + out.writeByte((byte) ((value & 0x7F)|0x80)); + } + + static public void packInt(DataOutput2 out, int value){ + // Optimize for the common case where value is small. This is particular important where our caller + // is SerializerBase.SER_STRING.serialize because most chars will be ASCII characters and hence in this range. + // credit Max Bolingbroke https://github.com/jankotek/MapDB/pull/489 + + int shift = (value & ~0x7F); //reuse variable + if (shift != 0) { + //$DELAY$ + shift = 31-Integer.numberOfLeadingZeros(value); + shift -= shift%7; // round down to nearest multiple of 7 + while(shift!=0){ + out.writeByte((byte) ((value>>>shift) & 0x7F)); + //$DELAY$ + shift-=7; + } + } + //$DELAY$ + out.writeByte((byte) ((value & 0x7F)|0x80)); + } + + /** + * Pack int into an output stream. + * It will occupy 1-5 bytes depending on value (lower values occupy smaller space) + * + * This method is same as {@link #packInt(DataOutput, int)}, + * but is optimized for values larger than 127. Usually it is recids. + * + * @param out String to put value into + * @param value to be serialized, must be non-negative + * @throws java.io.IOException in case of IO error + */ + + static public void packIntBigger(DataOutput out, int value) throws IOException { + //$DELAY$ + int shift = 31-Integer.numberOfLeadingZeros(value); + shift -= shift%7; // round down to nearest multiple of 7 + while(shift!=0){ + out.writeByte((byte) ((value>>>shift) & 0x7F)); + //$DELAY$ + shift-=7; + } + //$DELAY$ + out.writeByte((byte) ((value & 0x7F)|0x80)); + } + + public static int longHash(long h) { + //$DELAY$ + h = h * -7046029254386353131L; + h ^= h >> 32; + return (int)(h ^ h >> 16); + } + + public static int intHash(int h) { + //$DELAY$ + h = h * -1640531527; + return h ^ h >> 16; + } + + public static final long PACK_LONG_RESULT_MASK = 0xFFFFFFFFFFFFFFFL; + + + public static int getInt(byte[] buf, int pos) { + return + (((int)buf[pos++]) << 24) | + (((int)buf[pos++] & 0xFF) << 16) | + (((int)buf[pos++] & 0xFF) << 8) | + (((int)buf[pos] & 0xFF)); + } + + public static void putInt(byte[] buf, int pos,int v) { + buf[pos++] = (byte) (0xff & (v >> 24)); //TODO PERF is >>> faster here? Also invert 0xFF &? + buf[pos++] = (byte) (0xff & (v >> 16)); + buf[pos++] = (byte) (0xff & (v >> 8)); + buf[pos] = (byte) (0xff & (v)); + } + + + public static long getLong(byte[] buf, int pos) { + return + ((((long)buf[pos++]) << 56) | + (((long)buf[pos++] & 0xFF) << 48) | + (((long)buf[pos++] & 0xFF) << 40) | + (((long)buf[pos++] & 0xFF) << 32) | + (((long)buf[pos++] & 0xFF) << 24) | + (((long)buf[pos++] & 0xFF) << 16) | + (((long)buf[pos++] & 0xFF) << 8) | + (((long)buf[pos] & 0xFF))); + + } + + public static void putLong(byte[] buf, int pos,long v) { + buf[pos++] = (byte) (0xff & (v >> 56)); + buf[pos++] = (byte) (0xff & (v >> 48)); + buf[pos++] = (byte) (0xff & (v >> 40)); + buf[pos++] = (byte) (0xff & (v >> 32)); + buf[pos++] = (byte) (0xff & (v >> 24)); + buf[pos++] = (byte) (0xff & (v >> 16)); + buf[pos++] = (byte) (0xff & (v >> 8)); + buf[pos] = (byte) (0xff & (v)); + } + + public static void putLong(byte[] buf, int pos,long v, int vSize) { + for(int i=vSize-1; i>=0; i--){ + buf[i+pos] = (byte) (0xff & v); + v >>>=8; + } + } + + + public static int packInt(byte[] buf, int pos, int value){ + int pos2 = pos; + int shift = 31-Integer.numberOfLeadingZeros(value); + shift -= shift%7; // round down to nearest multiple of 7 + while(shift!=0){ + buf[pos++] = (byte) ((value>>>shift) & 0x7F); + shift-=7; + } + buf[pos++] = (byte) ((value & 0x7F)|0x80); + return pos-pos2; + } + + public static int packLong(byte[] buf, int pos, long value){ + int pos2 = pos; + + int shift = 63-Long.numberOfLeadingZeros(value); + shift -= shift%7; // round down to nearest multiple of 7 + while(shift!=0){ + buf[pos++] = (byte) ((value>>>shift) & 0x7F); + shift-=7; + } + buf[pos++] = (byte) ((value & 0x7F) | 0x80); + return pos - pos2; + } + + + public static int unpackInt(byte[] buf, int pos){ + int ret = 0; + byte v; + do{ + //$DELAY$ + v = buf[pos++]; + ret = (ret<<7 ) | (v & 0x7F); + }while((v&0x80)==0); + return ret; + } + + + public static long unpackLong(byte[] buf, int pos){ + long ret = 0; + byte v; + do{ + //$DELAY$ + v = buf[pos++]; + ret = (ret<<7 ) | (v & 0x7F); + }while((v&0x80)==0); + return ret; + } + + public static long getSixLong(byte[] buf, int pos) { + return + ((long) (buf[pos++] & 0xff) << 40) | + ((long) (buf[pos++] & 0xff) << 32) | + ((long) (buf[pos++] & 0xff) << 24) | + ((long) (buf[pos++] & 0xff) << 16) | + ((long) (buf[pos++] & 0xff) << 8) | + ((long) (buf[pos] & 0xff)); + } + + public static void putSixLong(byte[] buf, int pos, long value) { + if(CC.PARANOID && (value>>>48!=0)) + throw new AssertionError(); + + buf[pos++] = (byte) (0xff & (value >> 40)); + buf[pos++] = (byte) (0xff & (value >> 32)); + buf[pos++] = (byte) (0xff & (value >> 24)); + buf[pos++] = (byte) (0xff & (value >> 16)); + buf[pos++] = (byte) (0xff & (value >> 8)); + buf[pos] = (byte) (0xff & (value)); + } + + + + public static long nextPowTwo(final long a) + { + return 1L << (64 - Long.numberOfLeadingZeros(a - 1L)); + } + + public static int nextPowTwo(final int a) + { + return 1 << (32 - Integer.numberOfLeadingZeros(a - 1)); + } + + public static void readFully(InputStream in, byte[] data, int offset, int len) throws IOException { + len+=offset; + for(; offset0) + rem-=f.write(buf); + } + + + public static void readFully(@NotNull FileChannel f, @NotNull ByteBuffer buf, long offset ) throws IOException { + int rem = buf.remaining(); + while(rem>0) { + int read = f.read(buf, offset); + if(read<0) + throw new EOFException(); + rem-=read; + offset+=read; + } + } + + + public static void skipFully(InputStream in, long length) throws IOException { + while ((length -= in.skip(length)) > 0); + } + + public static long fillLowBits(int bitCount) { + long ret = 0; + for(;bitCount>0;bitCount--){ + ret = (ret<<1)|1; + } + return ret; + } + + + public static long parity1Set(long i) { + if(CC.PARANOID && (i&1)!=0) + throw new DBException.PointerChecksumBroken(); + return i | ((Long.bitCount(i)+1)%2); + } + + public static int parity1Set(int i) { + if(CC.PARANOID && (i&1)!=0) + throw new DBException.PointerChecksumBroken(); + return i | ((Integer.bitCount(i)+1)%2); + } + + public static long parity1Get(long i) { + if(Long.bitCount(i)%2!=1){ + throw new DBException.PointerChecksumBroken(); + } + return i&0xFFFFFFFFFFFFFFFEL; + } + + + public static int parity1Get(int i) { + if(Integer.bitCount(i)%2!=1){ + throw new DBException.PointerChecksumBroken(); + } + return i&0xFFFFFFFE; + } + + public static long parity3Set(long i) { + if(CC.PARANOID && (i&0x7)!=0) + throw new DBException.PointerChecksumBroken(); + return i | ((Long.bitCount(i)+1)%8); + } + + public static long parity3Get(long i) { + long ret = i&0xFFFFFFFFFFFFFFF8L; + if((Long.bitCount(ret)+1)%8!=(i&0x7)){ + throw new DBException.PointerChecksumBroken(); + } + return ret; + } + + public static long parity4Set(long i) { + if(CC.PARANOID && (i&0xF)!=0) + throw new DBException.PointerChecksumBroken(); + return i | ((Long.bitCount(i)+1)%16); + } + + public static long parity4Get(long i) { + long ret = i&0xFFFFFFFFFFFFFFF0L; + if((Long.bitCount(ret)+1)%16!=(i&0xF)){ + throw new DBException.PointerChecksumBroken(); + } + return ret; + } + + + public static long parity16Set(long i) { + if(CC.PARANOID && (i&0xFFFF)!=0) + throw new DBException.PointerChecksumBroken(); + return i | (DataIO.longHash(i+1)&0xFFFFL); + } + + public static long parity16Get(long i) { + long ret = i&0xFFFFFFFFFFFF0000L; + if((DataIO.longHash(ret+1)&0xFFFFL) != (i&0xFFFFL)){ + throw new DBException.PointerChecksumBroken(); + } + return ret; + } + + + /** + * Converts binary array into its hexadecimal representation. + * + * @param bb binary data + * @return hexadecimal string + */ + public static String toHexa( byte [] bb ) { + char[] HEXA_CHARS = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + char[] ret = new char[bb.length*2]; + for(int i=0;i> 4)]; + ret[i*2+1] = HEXA_CHARS[((bb[i] & 0x0F))]; + } + return new String(ret); + } + + /** + * Converts hexadecimal string into binary data + * @param s hexadecimal string + * @return binary data + * @throws NumberFormatException in case of string format error + */ + public static byte[] fromHexa(String s ) { + byte[] ret = new byte[s.length()/2]; + for(int i=0;i0; + } + + @Override + public int readPackedInt() { + return readInt(); + } + + @Override + public long readPackedLong() { + return readLong(); + } + + + @Override + public void unpackLongSkip(int count) { + byte[] b = buf; + int pos2 = this.pos; + while(count>0){ +// count -= (b[pos2++]&0x80)>>7; + //TODO go back to packed longs, remove code bellow + readLong(); + count--; + pos2+=8; + } + this.pos = pos2; + } + +} + diff --git a/src/main/java/org/mapdb/io/DataInput2ByteBuffer.java b/src/main/java/org/mapdb/io/DataInput2ByteBuffer.java new file mode 100644 index 000000000..3dea08bbe --- /dev/null +++ b/src/main/java/org/mapdb/io/DataInput2ByteBuffer.java @@ -0,0 +1,91 @@ +package org.mapdb.io; + +import java.nio.ByteBuffer; + +/** DataInput on top of {@link ByteBuffer} */ +public final class DataInput2ByteBuffer implements DataInput2 { + + protected final ByteBuffer buf; + + public DataInput2ByteBuffer(ByteBuffer buf) { + this.buf = buf; + } + + public void readFully(byte[] b, int off, int len) { + buf.get(b, off,len); + } + + @Override + public int skipBytes(final int n) { + buf.position(buf.position()+n); + return n; + } + + @Override + public boolean readBoolean() { + return buf.get() == 1; + } + + @Override + public byte readByte() { + return buf.get(); + } + + @Override + public int readUnsignedByte() { + return buf.get() & 0xff; + } + + @Override + public short readShort() { + return buf.getShort(); + } + + @Override + public char readChar() { + return buf.getChar(); + } + + @Override + public int readInt() { + return buf.getInt(); + } + + @Override + public long readLong() { + return buf.getLong(); + } + + + @Override + public int available() { + return buf.remaining(); + } + + @Override + public boolean availableMore() { + return available()>0; + } + + @Override + public int readPackedInt() { + return readInt(); + } + + @Override + public long readPackedLong() { + return readLong(); + } + + + @Override + public void unpackLongSkip(int count) { + while(count>0){ + //TODO go back to packed longs, remove code bellow + readLong(); + count--; + } + } + +} + diff --git a/src/main/java/org/mapdb/io/DataInputToStream.java b/src/main/java/org/mapdb/io/DataInputToStream.java new file mode 100644 index 000000000..f547aa9f6 --- /dev/null +++ b/src/main/java/org/mapdb/io/DataInputToStream.java @@ -0,0 +1,42 @@ +package org.mapdb.io; + +import java.io.Closeable; +import java.io.DataInput; +import java.io.IOException; +import java.io.InputStream; + +/** + * Wraps {@code DataInput} into {@code InputStream} + */ +public final class DataInputToStream extends InputStream { + + protected final DataInput2 in; + + public DataInputToStream(DataInput2 in) { + this.in = in; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + in.readFully(b,off,len); + return len; + } + + @Override + public long skip(long n) throws IOException { + n = Math.min(n, Integer.MAX_VALUE); + //$DELAY$ + return in.skipBytes((int) n); + } + + @Override + public void close() throws IOException { + if(in instanceof Closeable) + ((Closeable) in).close(); + } + + @Override + public int read() throws IOException { + return in.readUnsignedByte(); + } +} diff --git a/src/main/java/org/mapdb/io/DataOutput2.java b/src/main/java/org/mapdb/io/DataOutput2.java new file mode 100644 index 000000000..734ab9f77 --- /dev/null +++ b/src/main/java/org/mapdb/io/DataOutput2.java @@ -0,0 +1,62 @@ +package org.mapdb.io; + +import java.io.DataOutput; +import java.io.IOException; + + +public interface DataOutput2{ + + /** + * Give a hint to DataOutput about total size of serialized data. + * This may prevent `byte[]` resize. And huge records might be placed into temporary file + */ + void sizeHint(int size); + + /** write int in packed form */ + void writePackedInt(int value); + + /** write long in packed form */ + void writePackedLong(long value); + + /** write recid, recids have extra parity bit to detect data corruption */ + void writeRecid(long recid); + + /** write recid in packed form, recids have extra parity bit to detect data corruption */ + void writePackedRecid(long recid); + + /** copy content of this DataOutput2 into `ByteArray` */ + byte[] copyBytes(); + + + void writeBoolean(boolean v); + + void writeByte(int v); + + void writeShort(int v); + + void writeChar(int v); + + void writeInt(int v); + + void writeLong(long v); + + void writeFloat(float v); + + void writeDouble(double v); + + void writeBytes(String s); + + void writeChars(String s); + + void writeUTF(String s); + + @Deprecated //TODO temp method for compatibility + default void packInt(int i){ + writePackedInt(i); + } + + void write(int bytee); //TODO remove this method? compatibility with java.io.DataOutput + + void write(byte[] buf); + void write(byte b[], int off, int len); +} diff --git a/src/main/java/org/mapdb/io/DataOutput2ByteArray.java b/src/main/java/org/mapdb/io/DataOutput2ByteArray.java new file mode 100644 index 000000000..25f76209f --- /dev/null +++ b/src/main/java/org/mapdb/io/DataOutput2ByteArray.java @@ -0,0 +1,244 @@ +package org.mapdb.io; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; + +/** + * Output of serialization + */ +public class DataOutput2ByteArray extends OutputStream implements DataOutput2{ + + public byte[] buf; + public int pos; //TODO private fields vs getters? + public int sizeMask; + + + public DataOutput2ByteArray(){ + pos = 0; + buf = new byte[128]; //PERF take hint from serializer for initial size + sizeMask = 0xFFFFFFFF-(buf.length-1); + } + + + @Override public byte[] copyBytes(){ + return Arrays.copyOf(buf, pos); + } + + /** + * make sure there will be enough space in buffer to write N bytes + * @param n number of bytes which can be safely written after this method returns + */ + protected void ensureAvail(int n) { + //$DELAY$ + n+=pos; + if ((n&sizeMask)!=0) { + grow(n); + } + } + + private void grow(int n) { + //$DELAY$ + int newSize = Math.max(DataIO.nextPowTwo(n),buf.length); + sizeMask = 0xFFFFFFFF-(newSize-1); + buf = Arrays.copyOf(buf, newSize); + } + + + @Override + public void write(final int b){ + ensureAvail(1); + //$DELAY$ + buf[pos++] = (byte) b; + } + + @Override + public void write(byte[] b){ + write(b,0,b.length); + } + + @Override + public void write(final byte[] b, final int off, final int len){ + ensureAvail(len); + //$DELAY$ + System.arraycopy(b, off, buf, pos, len); + pos += len; + } + + @Override + public void writeBoolean(final boolean v){ + ensureAvail(1); + //$DELAY$ + buf[pos++] = (byte) (v ? 1 : 0); + } + + @Override + public void writeByte(final int v){ + ensureAvail(1); + //$DELAY$ + buf[pos++] = (byte) (v); + } + + @Override + public void writeShort(final int v){ + ensureAvail(2); + //$DELAY$ + buf[pos++] = (byte) (0xff & (v >> 8)); + //$DELAY$ + buf[pos++] = (byte) (0xff & (v)); + } + + @Override + public void writeChar(final int v){ + ensureAvail(2); + buf[pos++] = (byte) (v>>>8); + buf[pos++] = (byte) (v); + } + + @Override + public void writeInt(final int v){ + ensureAvail(4); + buf[pos++] = (byte) (0xff & (v >> 24)); + //$DELAY$ + buf[pos++] = (byte) (0xff & (v >> 16)); + buf[pos++] = (byte) (0xff & (v >> 8)); + //$DELAY$ + buf[pos++] = (byte) (0xff & (v)); + } + + @Override + public void writeLong(final long v){ + ensureAvail(8); + buf[pos++] = (byte) (0xff & (v >> 56)); + buf[pos++] = (byte) (0xff & (v >> 48)); + //$DELAY$ + buf[pos++] = (byte) (0xff & (v >> 40)); + buf[pos++] = (byte) (0xff & (v >> 32)); + buf[pos++] = (byte) (0xff & (v >> 24)); + //$DELAY$ + buf[pos++] = (byte) (0xff & (v >> 16)); + buf[pos++] = (byte) (0xff & (v >> 8)); + buf[pos++] = (byte) (0xff & (v)); + //$DELAY$ + } + + @Override + public void writeFloat(final float v){ + writeInt(Float.floatToIntBits(v)); + } + + @Override + public void writeDouble(final double v){ + writeLong(Double.doubleToLongBits(v)); + } + + @Override + public void writeBytes(final String s){ + writeUTF(s); + } + + @Override + public void writeChars(final String s){ + writeUTF(s); + } + + @Override + public void writeUTF(final String s){ + final int len = s.length(); + writePackedInt(len); + for (int i = 0; i < len; i++) { + //$DELAY$ + int c = (int) s.charAt(i); + writePackedInt(c); + } + } + + + //TODO evaluate packed methods + public void packInt(int value){ + writeInt(value); + } +// public void packInt(int value){ +// ensureAvail(5); //ensure worst case bytes +// +// // Optimize for the common case where value is small. This is particular important where our caller +// // is SerializerBase.SER_STRING.serialize because most chars will be ASCII characters and hence in this range. +// // credit Max Bolingbroke https://github.com/jankotek/MapDB/pull/489 +// int shift = (value & ~0x7F); //reuse variable +// if (shift != 0) { +// shift = 31 - Integer.numberOfLeadingZeros(value); +// shift -= shift % 7; // round down to nearest multiple of 7 +// while (shift != 0) { +// buf[pos++] = (byte) ((value >>> shift) & 0x7F); +// shift -= 7; +// } +// } +// buf[pos++] = (byte) ((value & 0x7F)| 0x80); +// } +// +// public void packIntBigger(int value){ +// ensureAvail(5); //ensure worst case bytes +// int shift = 31-Integer.numberOfLeadingZeros(value); +// shift -= shift%7; // round down to nearest multiple of 7 +// while(shift!=0){ +// buf[pos++] = (byte) ((value>>>shift) & 0x7F); +// shift-=7; +// } +// buf[pos++] = (byte) ((value & 0x7F)|0x80); +// } +// +// public void packLong(long value) { +// ensureAvail(10); //ensure worst case bytes +// int shift = 63-Long.numberOfLeadingZeros(value); +// shift -= shift%7; // round down to nearest multiple of 7 +// while(shift!=0){ +// buf[pos++] = (byte) ((value>>>shift) & 0x7F); +// shift-=7; +// } +// buf[pos++] = (byte) ((value & 0x7F) | 0x80); +// } +// +// +// public void packLongArray(long[] array, int fromIndex, int toIndex ) { +// for(int i=fromIndex;i>>shift) & 0x7F); +// shift-=7; +// } +// buf[pos++] = (byte) ((value & 0x7F) | 0x80); +// } +// } + + @Override + public void sizeHint(int size) { + ensureAvail(size); + } + + @Override + public void writePackedInt(int value){ + //TODO packed int and long + writeInt(value); + } + + @Override + public void writePackedLong(long value){ + writeLong(value); + } + + @Override + public void writeRecid(long recid){ + //TODO 6 bytes + //TODO parity bit + writeLong(recid); + } + + @Override + public void writePackedRecid(long recid){ + //TODO parity bit + writePackedLong(recid); + } +} diff --git a/src/main/java/org/mapdb/list/KernelList.java b/src/main/java/org/mapdb/list/KernelList.java new file mode 100644 index 000000000..80f4b37f1 --- /dev/null +++ b/src/main/java/org/mapdb/list/KernelList.java @@ -0,0 +1,157 @@ +package org.mapdb.list; + +import org.mapdb.ser.Serializer; +import org.mapdb.ser.Serializers; +import org.mapdb.store.Store; + +import java.util.*; + +public class KernelList + extends AbstractList + implements List, RandomAccess { + + private static final Serializer KERNEL_SER = Serializers.LONG_ARRAY; + + private final Store kernelStore; + private final Store entryStore; + private final long recid; + private final Serializer ser; + + public KernelList(Store kernelStore, Store entryStore, long recid, Serializer ser) { + this.kernelStore = kernelStore; + this.entryStore = entryStore; + this.recid = recid; + this.ser = ser; + } + + + public static class Maker { + private final Store store; + + private Store entryStore = null; + private final Serializer ser; + private final long recid; + + public Maker(Store store, long recid, Serializer ser) { + this.store = store; + this.entryStore = store; + this.recid = recid; + this.ser = ser; + } + + public static KernelList.Maker newList(Store store, Serializer ser) { + long recid = store.put(new long[]{}, KERNEL_SER); + return new KernelList.Maker(store, recid, ser); + } + + public Maker entryStore(Store store){ + this.entryStore = store; + return this; + } + + public KernelList make(){ + return new KernelList(store, entryStore, recid, ser); + } + } + + + @Override + public E get(int index) { + long entryRecid = getKernel()[index]; + return entryStore.get(entryRecid, ser); + } + + @Override + public int size() { + return getKernel().length; + } + + @Override + public boolean add(E e) { + long[] kernel = getKernel(); + kernel = Arrays.copyOf(kernel, kernel.length+1); + long newRecid = entryStore.put(e, ser); + kernel[kernel.length-1] = newRecid; + storeKernel(kernel); + return true; + } + + @Override + public void add(int index, E e) { + long[] kernel = getKernel(); + if(index<0 || index>kernel.length) + throw new IndexOutOfBoundsException(); + + long[] kernel2 = Arrays.copyOf(kernel, kernel.length+1); + System.arraycopy(kernel, index, kernel2, index+1, kernel.length-index); + + long newRecid = entryStore.put(e, ser); + kernel2[index] = newRecid; + storeKernel(kernel2); + } + + @Override + public boolean addAll(Collection c) { + long[] kernel = getKernel(); + int pos = kernel.length; + kernel = Arrays.copyOf(kernel, kernel.length+c.size()); + for(E e:c){ + long newRecid = entryStore.put(e, ser); + kernel[pos++] = newRecid; + } + if(pos!=kernel.length) + throw new ConcurrentModificationException(); + storeKernel(kernel); + return true; + } + + @Override + public boolean addAll(int index, Collection c) { + long[] kernel = getKernel(); + if(index<0 || index>kernel.length) + throw new IndexOutOfBoundsException(); + int csize = c.size(); + long[] kernel2 = Arrays.copyOf(kernel, kernel.length+csize); + System.arraycopy(kernel, index, kernel2, index+csize, kernel.length-index); + kernel=null; //release memory for GC + int pos = index; + for(E e:c){ + long newRecid = entryStore.put(e, ser); + kernel2[pos++] = newRecid; + } + if(pos!=csize+index) + throw new ConcurrentModificationException(); + storeKernel(kernel2); + return true; + } + + @Override + public E remove(int index) { + long[] kernel = getKernel(); + long eRecid = kernel[index]; + E ret = entryStore.getAndDelete(eRecid, ser); + long[] kernel2 = Arrays.copyOf(kernel, kernel.length-1); + System.arraycopy(kernel, index+1, kernel2, index, kernel2.length-index); + storeKernel(kernel2); + return ret; + } + + @Override + public E set(int index, E element) { + long[] kernel = getKernel(); + return entryStore.getAndUpdate(kernel[index], ser, element); + } + + protected void storeKernel(long[] kernel) { + for(long recid:kernel) { + if (recid <= 0) + throw new ConcurrentModificationException(); + } + kernelStore.update(recid, KERNEL_SER, kernel); + } + + protected long[] getKernel(){ + return kernelStore.get(recid, KERNEL_SER); + } + +} diff --git a/src/main/java/org/mapdb/list/MonolithList.java b/src/main/java/org/mapdb/list/MonolithList.java new file mode 100644 index 000000000..8901e6128 --- /dev/null +++ b/src/main/java/org/mapdb/list/MonolithList.java @@ -0,0 +1,115 @@ +package org.mapdb.list; + +import org.mapdb.ser.ArrayListSerializer; +import org.mapdb.ser.Serializer; +import org.mapdb.store.Store; + +import java.util.*; + +public class MonolithList + extends AbstractList + implements List, RandomAccess { + + public static class Maker { + private final Store store; + private final Serializer ser; + private final long recid; + + public Maker(Store store, long recid, Serializer ser) { + this.store = store; + this.recid = recid; + this.ser = ser; + } + + public static Maker newList(Store store, Serializer ser) { + long recid = store.put(new ArrayList(), new ArrayListSerializer(ser)); + return new Maker(store, recid, ser); + } + + public MonolithList make(){ + return new MonolithList(store, recid, ser); + } + } + + + private final Store store; + private final long recid; + private final Serializer ser; + private final Serializer> listSer; + + public MonolithList(Store store, long recid, Serializer ser) { + this.store = store; + this.recid = recid; + this.ser = ser; + this.listSer = new ArrayListSerializer(ser); + } + + + @Override + public E get(int index) { + ArrayList list = store.get(recid, listSer); + return list.get(index); + } + + @Override + public int size() { + ArrayList list = store.get(recid, listSer); + return list.size(); + } + + @Override + public boolean add(E e) { + ArrayList list = getClone(); + list.add(e); + store(list); + return true; + } + + @Override + public E set(int index, E element) { + ArrayList list = getClone(); + E e=list.set(index,element); + store(list); + return e; + } + + @Override + public void add(int index, E element) { + ArrayList list = getClone(); + list.add(index,element); + store(list); + } + + @Override + public boolean addAll(int index, Collection c) { + ArrayList list = getClone(); + list.addAll(index, c); + store(list); + return true; + } + + @Override + public boolean addAll(Collection c) { + ArrayList list = getClone(); + list.addAll(c); + store(list); + return true; + } + + @Override + public E remove(int index) { + ArrayList list = getClone(); + E e=list.remove(index); + store(list); + return e; + } + + protected ArrayList getClone() { + return (ArrayList) store.get(recid, listSer).clone(); + } + + protected void store(ArrayList list) { + store.update(recid, listSer, list); + } + +} diff --git a/src/main/java/org/mapdb/Atomic.java b/src/main/java/org/mapdb/record/Atomic.java similarity index 82% rename from src/main/java/org/mapdb/Atomic.java rename to src/main/java/org/mapdb/record/Atomic.java index 85e4928f1..b7e45d0ed 100644 --- a/src/main/java/org/mapdb/Atomic.java +++ b/src/main/java/org/mapdb/record/Atomic.java @@ -21,33 +21,38 @@ * Expert Group and released to the public domain, as explained at * http://creativecommons.org/licenses/publicdomain */ -package org.mapdb; +package org.mapdb.record; -import java.io.DataInput; -import java.io.IOException; +import org.mapdb.ser.Serializer; +import org.mapdb.ser.Serializers; +import org.mapdb.store.Store; /** + *

* A small toolkit of classes that support lock-free thread-safe * programming on single records. In essence, the classes here * provide provide an atomic conditional update operation of the form: - *

+ *

* *
  *   boolean compareAndSet(expectedValue, updateValue);
  * 
* - *

This method (which varies in argument types across different + *

+ * This method (which varies in argument types across different * classes) atomically sets a record to the {@code updateValue} if it * currently holds the {@code expectedValue}, reporting {@code true} on * success. Classes jere also contain methods to get and * unconditionally set values. + *

* - *

The specifications of these methods enable to + * The specifications of these methods enable to * employ more efficient internal DB locking. CompareAndSwap * operation is typically faster than using transactions, global lock or other * concurrent protection. * - *

Instances of classes + *

+ * Instances of classes * {@link Atomic.Boolean}, * {@link Atomic.Integer}, * {@link Atomic.Long}, @@ -58,31 +63,35 @@ * methods for that type. For example, classes {@code Atomic.Long} and * {@code Atomic.Integer} provide atomic increment methods. One * application is to generate unique keys for Maps: - * + *

*
  *    Atomic.Long id = Atomic.getLong("mapId");
  *    map.put(id.getAndIncrement(), "something");
  * 
* - *

Atomic classes are designed primarily as building blocks for + *

+ * Atomic classes are designed primarily as building blocks for * implementing non-blocking data structures and related infrastructure * classes. The {@code compareAndSet} method is not a general * replacement for locking. It applies only when critical updates for an * object are confined to a single record. + *

* - *

Atomic classes are not general purpose replacements for + * Atomic classes are not general purpose replacements for * {@code java.lang.Integer} and related classes. They do not * define methods such as {@code hashCode} and * {@code compareTo}. (Because atomic records are expected to be * mutated, they are poor choices for hash table keys.) Additionally, * classes are provided only for those types that are commonly useful in * intended applications. Other types has to be wrapped into general {@link Atomic.Var} - *

+ *

+ * * You can also hold floats using * {@link java.lang.Float#floatToIntBits} and * {@link java.lang.Float#intBitsToFloat} conversions, and doubles using * {@link java.lang.Double#doubleToLongBits} and * {@link java.lang.Double#longBitsToDouble} conversions. + *

* */ final public class Atomic { @@ -102,11 +111,11 @@ public final static class Integer extends Number { private static final long serialVersionUID = 4615119399830853054L; - protected final Engine engine; + protected final Store store; protected final long recid; - public Integer(Engine engine, long recid) { - this.engine = engine; + public Integer(Store store, long recid) { + this.store = store; this.recid = recid; } @@ -123,7 +132,7 @@ public long getRecid(){ * @return the current value */ public final int get() { - return engine.get(recid, Serializer.INTEGER); + return store.get(recid, Serializers.INTEGER); } /** @@ -132,7 +141,7 @@ public final int get() { * @param newValue the new value */ public final void set(int newValue) { - engine.update(recid, newValue, Serializer.INTEGER); + store.update(recid, Serializers.INTEGER, newValue); } @@ -143,12 +152,9 @@ public final void set(int newValue) { * @return the previous value */ public final int getAndSet(int newValue) { - //$DELAY$ for (;;) { int current = get(); - //$DELAY$ if (compareAndSet(current, newValue)) { - //$DELAY$ return current; } } @@ -164,7 +170,7 @@ public final int getAndSet(int newValue) { * the actual value was not equal to the expected value. */ public final boolean compareAndSet(int expect, int update) { - return engine.compareAndSwap(recid, expect, update, Serializer.INTEGER); + return store.compareAndUpdate(recid, Serializers.INTEGER, expect, update); } @@ -174,14 +180,10 @@ public final boolean compareAndSet(int expect, int update) { * @return the previous value */ public final int getAndIncrement() { - //$DELAY$ for (;;) { - //$DELAY$ int current = get(); int next = current + 1; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return current; } } @@ -193,14 +195,10 @@ public final int getAndIncrement() { * @return the previous value */ public final int getAndDecrement() { - //$DELAY$ for (;;) { - //$DELAY$ int current = get(); int next = current - 1; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return current; } } @@ -213,14 +211,10 @@ public final int getAndDecrement() { * @return the previous value */ public final int getAndAdd(int delta) { - //$DELAY$ for (;;) { - //$DELAY$ int current = get(); int next = current + delta; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return current; } } @@ -232,14 +226,10 @@ public final int getAndAdd(int delta) { * @return the updated value */ public final int incrementAndGet() { - //$DELAY$ for (;;) { - //$DELAY$ int current = get(); int next = current + 1; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return next; } } @@ -251,14 +241,10 @@ public final int incrementAndGet() { * @return the updated value */ public final int decrementAndGet() { - //$DELAY$ for (;;) { - //$DELAY$ int current = get(); int next = current - 1; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return next; } } @@ -271,14 +257,10 @@ public final int decrementAndGet() { * @return the updated value */ public final int addAndGet(int delta) { - //$DELAY$ for (;;) { - //$DELAY$ int current = get(); int next = current + delta; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return next; } } @@ -324,11 +306,11 @@ public final static class Long extends Number{ private static final long serialVersionUID = 2882620413591274781L; - protected final Engine engine; + protected final Store store; protected final long recid; - public Long(Engine engine, long recid) { - this.engine = engine; + public Long(Store store, long recid) { + this.store = store; this.recid = recid; } @@ -346,7 +328,7 @@ public long getRecid(){ * @return the current value */ public final long get() { - return engine.get(recid, Serializer.LONG); + return store.get(recid, Serializers.LONG); } /** @@ -355,7 +337,7 @@ public final long get() { * @param newValue the new value */ public final void set(long newValue) { - engine.update(recid, newValue, Serializer.LONG); + store.update(recid, Serializers.LONG, newValue); } @@ -366,13 +348,9 @@ public final void set(long newValue) { * @return the previous value */ public final long getAndSet(long newValue) { - //$DELAY$ while (true) { - //$DELAY$ long current = get(); - //$DELAY$ if (compareAndSet(current, newValue)) { - //$DELAY$ return current; } } @@ -388,7 +366,7 @@ public final long getAndSet(long newValue) { * the actual value was not equal to the expected value. */ public final boolean compareAndSet(long expect, long update) { - return engine.compareAndSwap(recid, expect, update, Serializer.LONG); + return store.compareAndUpdate(recid, Serializers.LONG, expect, update); } @@ -398,14 +376,10 @@ public final boolean compareAndSet(long expect, long update) { * @return the previous value */ public final long getAndIncrement() { - //$DELAY$ while (true) { - //$DELAY$ long current = get(); long next = current + 1; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return current; } } @@ -417,14 +391,10 @@ public final long getAndIncrement() { * @return the previous value */ public final long getAndDecrement() { - //$DELAY$ while (true) { - //$DELAY$ long current = get(); long next = current - 1; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return current; } } @@ -437,14 +407,10 @@ public final long getAndDecrement() { * @return the previous value */ public final long getAndAdd(long delta) { - //$DELAY$ while (true) { - //$DELAY$ long current = get(); long next = current + delta; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return current; } } @@ -456,14 +422,10 @@ public final long getAndAdd(long delta) { * @return the updated value */ public final long incrementAndGet() { - //$DELAY$ for (;;) { - //$DELAY$ long current = get(); long next = current + 1; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return next; } } @@ -475,14 +437,10 @@ public final long incrementAndGet() { * @return the updated value */ public final long decrementAndGet() { - //$DELAY$ for (;;) { - //$DELAY$ long current = get(); long next = current - 1; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return next; } } @@ -495,14 +453,10 @@ public final long decrementAndGet() { * @return the updated value */ public final long addAndGet(long delta) { - //$DELAY$ for (;;) { - //$DELAY$ long current = get(); long next = current + delta; - //$DELAY$ if (compareAndSet(current, next)) { - //$DELAY$ return next; } } @@ -541,11 +495,11 @@ public double doubleValue() { */ public final static class Boolean { - protected final Engine engine; + protected final Store store; protected final long recid; - public Boolean(Engine engine, long recid) { - this.engine = engine; + public Boolean(Store store, long recid) { + this.store = store; this.recid = recid; } @@ -563,7 +517,7 @@ public long getRecid(){ * @return the current value */ public final boolean get() { - return engine.get(recid, Serializer.BOOLEAN); + return store.get(recid, Serializers.BOOLEAN); } /** @@ -576,7 +530,7 @@ public final boolean get() { * the actual value was not equal to the expected value. */ public final boolean compareAndSet(boolean expect, boolean update) { - return engine.compareAndSwap(recid, expect, update, Serializer.BOOLEAN); + return store.compareAndUpdate(recid, Serializers.BOOLEAN, expect, update); } @@ -586,7 +540,7 @@ public final boolean compareAndSet(boolean expect, boolean update) { * @param newValue the new value */ public final void set(boolean newValue) { - engine.update(recid, newValue, Serializer.BOOLEAN); + store.update(recid, Serializers.BOOLEAN, newValue); } @@ -597,13 +551,9 @@ public final void set(boolean newValue) { * @return the previous value */ public final boolean getAndSet(boolean newValue) { - //$DELAY$ for (;;) { - //$DELAY$ boolean current = get(); - //$DELAY$ if (compareAndSet(current, newValue)) { - //$DELAY$ return current; } } @@ -624,11 +574,11 @@ public java.lang.String toString() { */ public final static class String{ - protected final Engine engine; + protected final Store store; protected final long recid; - public String(Engine engine, long recid) { - this.engine = engine; + public String(Store store, long recid) { + this.store = store; this.recid = recid; } @@ -650,7 +600,7 @@ public java.lang.String toString() { * @return the current value */ public final java.lang.String get() { - return engine.get(recid, Serializer.STRING_NOSIZE); + return store.get(recid, Serializers.STRING_NOSIZE); } /** @@ -663,7 +613,7 @@ public final java.lang.String get() { * the actual value was not equal to the expected value. */ public final boolean compareAndSet(java.lang.String expect, java.lang.String update) { - return engine.compareAndSwap(recid, expect, update, Serializer.STRING_NOSIZE); + return store.compareAndUpdate(recid, Serializers.STRING_NOSIZE, expect, update); } @@ -673,7 +623,7 @@ public final boolean compareAndSet(java.lang.String expect, java.lang.String upd * @param newValue the new value */ public final void set(java.lang.String newValue) { - engine.update(recid, newValue, Serializer.STRING_NOSIZE); + store.update(recid, Serializers.STRING_NOSIZE, newValue); } @@ -684,13 +634,9 @@ public final void set(java.lang.String newValue) { * @return the previous value */ public final java.lang.String getAndSet(java.lang.String newValue) { - //$DELAY$ for (;;) { - //$DELAY$ java.lang.String current = get(); - //$DELAY$ if (compareAndSet(current, newValue)) { - //$DELAY$ return current; } } @@ -703,23 +649,23 @@ public final java.lang.String getAndSet(java.lang.String newValue) { */ public static final class Var { - protected final Engine engine; + protected final Store store; protected final long recid; protected final Serializer serializer; - public Var(Engine engine, long recid, Serializer serializer) { - this.engine = engine; + public Var(Store store, long recid, Serializer serializer) { + this.store = store; this.recid = recid; this.serializer = serializer; } - - /** used for deserialization */ - protected Var(Engine engine, SerializerBase serializerBase, DataInput is, SerializerBase.FastArrayList objectStack) throws IOException { - objectStack.add(this); - this.engine = engine; - this.recid = DataIO.unpackLong(is); - this.serializer = (Serializer) serializerBase.deserialize(is,objectStack); - } +// +// /* used for deserialization */ +// protected Var(Store store, SerializerBase serializerBase, DataInput is, SerializerBase.FastArrayList objectStack) throws IOException { +// objectStack.add(this); +// this.store = store; +// this.recid = DataIO.unpackLong(is); +// this.serializer = (Serializer) serializerBase.deserialize(is,objectStack); +// } /** * @return recid under which value is saved @@ -740,7 +686,7 @@ public java.lang.String toString() { * @return the current value */ public final E get() { - return engine.get(recid, serializer); + return store.get(recid, serializer); } /** @@ -753,7 +699,7 @@ public final E get() { * the actual value was not equal to the expected value. */ public final boolean compareAndSet(E expect, E update) { - return engine.compareAndSwap(recid, expect, update, serializer); + return store.compareAndUpdate(recid, serializer, expect, update); } @@ -763,7 +709,7 @@ public final boolean compareAndSet(E expect, E update) { * @param newValue the new value */ public final void set(E newValue) { - engine.update(recid, newValue, serializer); + store.update(recid, serializer, newValue); } @@ -774,13 +720,9 @@ public final void set(E newValue) { * @return the previous value */ public final E getAndSet(E newValue) { - //$DELAY$ for (;;) { - //$DELAY$ E current = get(); - //$DELAY$ if (compareAndSet(current, newValue)) { - //$DELAY$ return current; } } diff --git a/src/main/java/org/mapdb/ser/ArrayDeltaSerializer.java b/src/main/java/org/mapdb/ser/ArrayDeltaSerializer.java new file mode 100644 index 000000000..3b24dc4f2 --- /dev/null +++ b/src/main/java/org/mapdb/ser/ArrayDeltaSerializer.java @@ -0,0 +1,81 @@ +package org.mapdb.ser; + +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; + +/** + * Created by jan on 2/28/16. + */ +public class ArrayDeltaSerializer extends ArraySerializer { + + private static final long serialVersionUID = -930920902390439234L; + + + public ArrayDeltaSerializer(Serializer serializer) { + super(serializer); + } + + @Override + public void valueArraySerialize(DataOutput2 out, Object[] vals2) { + Object[] vals = (Object[]) vals2; + if (vals.length == 0) + return; + //write first array + Object[] prevKey = (Object[]) vals[0]; + out.packInt(prevKey.length); + for (Object key : prevKey) { + serializer.serialize(out, (T) key); + } + + //write remaining arrays + for (int i = 1; i < vals.length; i++) { + Object[] key = (Object[]) vals[i]; + //calculate number of entries equal with prevKey + int len = Math.min(key.length, prevKey.length); + int pos = 0; + while (pos < len && (key[pos] == prevKey[pos] || serializer.equals((T) key[pos], (T) prevKey[pos]))) { + pos++; + } + out.packInt(pos); + //write remaining bytes + out.packInt(key.length - pos); + for (; pos < key.length; pos++) { + serializer.serialize(out, (T) key[pos]); + } + prevKey = key; + } + + } + + @Override + public Object[] valueArrayDeserialize(DataInput2 in, final int size) { + Object[] ret = new Object[size]; + if (size == 0) + return ret; + int ss = in.unpackInt(); + Object[] prevKey = new Object[ss]; + for (int i = 0; i < ss; i++) { + prevKey[i] = serializer.deserialize(in, -1); + } + ret[0] = prevKey; + for (int i = 1; i < size; i++) { + //number of items shared with prev + int shared = in.unpackInt(); + //number of items unique to this array + int unq = in.unpackInt(); + Object[] key = new Object[shared + unq]; + //copy items from prev array + System.arraycopy(prevKey, 0, key, 0, shared); + //and read rest + for (; shared < key.length; shared++) { + key[shared] = serializer.deserialize(in, -1); + } + ret[i] = key; + prevKey = key; + } + return ret; + } + +} diff --git a/src/main/java/org/mapdb/ser/ArrayListSerializer.java b/src/main/java/org/mapdb/ser/ArrayListSerializer.java new file mode 100644 index 000000000..516307f64 --- /dev/null +++ b/src/main/java/org/mapdb/ser/ArrayListSerializer.java @@ -0,0 +1,41 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.util.ArrayList; + +public class ArrayListSerializer implements Serializer> { + + protected final Serializer ser; + + public ArrayListSerializer(Serializer ser) { + this.ser = ser; + } + + @Override + public void serialize(@NotNull DataOutput2 out, @NotNull ArrayList list) { + out.writePackedInt(list.size()); + for(E e:list){ + ser.serialize(out,e); + } + } + + @Override + public ArrayList deserialize(@NotNull DataInput2 input) { + final int size = input.readPackedInt(); + ArrayList list = new ArrayList<>(size); + for(int i=0;i extends DefaultGroupSerializer { + + private static final long serialVersionUID = -982394293898234253L; + protected final Serializer serializer; + protected final Class componentType; + + + /** + * Wraps given serializer and produces Object[] serializer. + * To produce array with different component type, specify extra class. + */ + public ArraySerializer(Serializer serializer) { + this(serializer, null); + } + + + /** + * Wraps given serializer and produces array serializer. + * + * @param serializer + * @param componentType type of array which will be created on deserialization + */ + public ArraySerializer(Serializer serializer, Class componentType) { + if (serializer == null) + throw new NullPointerException("null serializer"); + this.serializer = serializer; + this.componentType = componentType!=null + ? componentType + : (Class)Object.class; + } + +// /** used for deserialization */ +// @SuppressWarnings("unchecked") +// protected Array(SerializerBase serializerBase, DataInput2 is, SerializerBase.FastArrayList objectStack) { +// objectStack.add(this); +// this.serializer = (Serializer) serializerBase.deserialize(is,objectStack); +// } + + + @Override + public void serialize(DataOutput2 out, T[] value) { + out.packInt(value.length); + for (T a : value) { + serializer.serialize(out, a); + } + } + + @Override + public T[] deserialize(DataInput2 in) { + int size = in.unpackInt(); + T[] ret = (T[]) Array.newInstance(componentType, size); + for (int i = 0; i < ret.length; i++) { + ret[i] = serializer.deserialize(in, -1); + } + return ret; + + } + + @Nullable + @Override + public Class serializedType() { + return Object[].class; + } + + @Override + public boolean isTrusted() { + return serializer.isTrusted(); + } + + @Override + public boolean equals(T[] a1, T[] a2) { + if (a1 == a2) + return true; + if (a1 == null || a1.length != a2.length) + return false; + + for (int i = 0; i < a1.length; i++) { + if (!serializer.equals(a1[i], a2[i])) + return false; + } + return true; + } + + @Override + public int hashCode(T[] objects, int seed) { + seed += objects.length; + for (T a : objects) { + seed = (-1640531527) * seed + serializer.hashCode(a, seed); + } + return seed; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + return serializer.equals(((ArraySerializer) o).serializer); + } + + @Override + public int hashCode() { + return serializer.hashCode(); + } + + + @Override + public int compare(Object[] o1, Object[] o2) { + int len = Math.min(o1.length, o2.length); + int r; + for (int i = 0; i < len; i++) { + Object a1 = o1[i]; + Object a2 = o2[i]; + + if (a1 == a2) { //this case handles both nulls + r = 0; + } else if (a1 == null) { + r = 1; //null is positive infinity, always greater than anything else + } else if (a2 == null) { + r = -1; + } else { + r = serializer.compare((T) a1, (T) a2); + ; + } + if (r != 0) + return r; + } + return SerializerUtils.compareInt(o1.length, o2.length); + } + +} diff --git a/src/main/java/org/mapdb/ser/ArrayTupleSerializer.java b/src/main/java/org/mapdb/ser/ArrayTupleSerializer.java new file mode 100644 index 000000000..e7e31803d --- /dev/null +++ b/src/main/java/org/mapdb/ser/ArrayTupleSerializer.java @@ -0,0 +1,220 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.CC; +import org.mapdb.io.DataIO; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Serializer for tuples. It serializes fixed size array, where each array index can use different serializer. + * + * It takes array of serializes in constructor parameter. All tuples (arrays) must have the same size. + */ +public class ArrayTupleSerializer implements GroupSerializer { + + protected final Serializer[] ser; + protected final Comparator[] comp; + protected final int size; + + public ArrayTupleSerializer(Serializer[] serializers, Comparator[] comparators) { + this.ser = serializers.clone(); + this.comp = comparators.clone(); + this.size = ser.length; + } + + public ArrayTupleSerializer(Serializer... serializers) { + this.ser = serializers.clone(); + this.comp = ser; + this.size = ser.length; + } + + + protected Object[] cast(Object o){ + if(CC.ASSERT && ((Object[])o).length%size!=0) { + throw new AssertionError(); + } + return (Object[])o; + } + + @Override + public void serialize(@NotNull DataOutput2 out, @NotNull Object[] value) { + for(int i=0;i { + @Override + public void serialize(DataOutput2 out, BigDecimal value) { + Serializers.BYTE_ARRAY.serialize(out, value.unscaledValue().toByteArray()); + out.packInt(value.scale()); + } + + @Override + public BigDecimal deserialize(DataInput2 in) { + return new BigDecimal(new BigInteger( + Serializers.BYTE_ARRAY.deserialize(in, -1)), + in.unpackInt()); + } + + @Nullable + @Override + public Class serializedType() { + return BigDecimal.class; + } + + @Override + public boolean isTrusted() { + return true; + } +} diff --git a/src/main/java/org/mapdb/ser/BigIntegerSerializer.java b/src/main/java/org/mapdb/ser/BigIntegerSerializer.java new file mode 100644 index 000000000..73066739e --- /dev/null +++ b/src/main/java/org/mapdb/ser/BigIntegerSerializer.java @@ -0,0 +1,34 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.math.BigInteger; + +/** + * Created by jan on 2/28/16. + */ +public class BigIntegerSerializer extends DefaultGroupSerializer { + @Override + public void serialize(DataOutput2 out, BigInteger value) { + Serializers.BYTE_ARRAY.serialize(out, value.toByteArray()); + } + + @Override + public BigInteger deserialize(DataInput2 in) { + return new BigInteger(Serializers.BYTE_ARRAY.deserialize(in)); + } + + @Nullable + @Override + public Class serializedType() { + return BigInteger.class; + } + + @Override + public boolean isTrusted() { + return true; + } +} diff --git a/src/main/java/org/mapdb/ser/BooleanSerializer.java b/src/main/java/org/mapdb/ser/BooleanSerializer.java new file mode 100644 index 000000000..3aacdfead --- /dev/null +++ b/src/main/java/org/mapdb/ser/BooleanSerializer.java @@ -0,0 +1,127 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by jan on 2/28/16. + */ +public class BooleanSerializer implements GroupSerializer { + + @Override + public void serialize(DataOutput2 out, Boolean value) { + out.writeBoolean(value); + } + + @Override + public Boolean deserialize(DataInput2 in) { + return in.readBoolean(); + } + + @Nullable + @Override + public Class serializedType() { + return Boolean.class; + } + + @Override + public int fixedSize() { + return 1; + } + + @Override + public boolean isTrusted() { + return true; + } + + + @Override + public int valueArraySearch(boolean[] keys, Boolean key) { + return Arrays.binarySearch(valueArrayToArray(keys), key); + } + + @Override + public int valueArraySearch(boolean[] keys, Boolean key, Comparator comparator) { + return Arrays.binarySearch(valueArrayToArray(keys), key, comparator); + } + + @Override + public void valueArraySerialize(DataOutput2 out, boolean[] vals) { + for (boolean b : ((boolean[]) vals)) { + out.writeBoolean(b); + } + } + + @Override + public boolean[] valueArrayDeserialize(DataInput2 in, int size) { + boolean[] ret = new boolean[size]; + for (int i = 0; i < size; i++) { + ret[i] = in.readBoolean(); + } + return ret; + } + + @Override + public Boolean valueArrayGet(boolean[] vals, int pos) { + return ((boolean[]) vals)[pos]; + } + + @Override + public int valueArraySize(boolean[] vals) { + return ((boolean[]) vals).length; + } + + @Override + public boolean[] valueArrayEmpty() { + return new boolean[0]; + } + + @Override + public boolean[] valueArrayPut(boolean[] vals, int pos, Boolean newValue) { + boolean[] array = (boolean[]) vals; + final boolean[] ret = Arrays.copyOf(array, array.length + 1); + if (pos < array.length) { + System.arraycopy(array, pos, ret, pos + 1, array.length - pos); + } + ret[pos] = newValue; + return ret; + + } + + @Override + public boolean[] valueArrayUpdateVal(boolean[] vals, int pos, Boolean newValue) { + boolean[] vals2 = ((boolean[]) vals).clone(); + vals2[pos] = newValue; + return vals2; + + } + + @Override + public boolean[] valueArrayFromArray(Object[] objects) { + boolean[] ret = new boolean[objects.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = (Boolean) objects[i]; + } + return ret; + } + + @Override + public boolean[] valueArrayCopyOfRange(boolean[] vals, int from, int to) { + return Arrays.copyOfRange((boolean[]) vals, from, to); + } + + @Override + public boolean[] valueArrayDeleteValue(boolean[] vals, int pos) { + boolean[] valsOrig = (boolean[]) vals; + boolean[] vals2 = new boolean[valsOrig.length - 1]; + System.arraycopy(vals, 0, vals2, 0, pos - 1); + System.arraycopy(vals, pos, vals2, pos - 1, vals2.length - (pos - 1)); + return vals2; + + } +} diff --git a/src/main/java/org/mapdb/ser/ByteArrayDelta2Serializer.java b/src/main/java/org/mapdb/ser/ByteArrayDelta2Serializer.java new file mode 100644 index 000000000..ded98d1d0 --- /dev/null +++ b/src/main/java/org/mapdb/ser/ByteArrayDelta2Serializer.java @@ -0,0 +1,184 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataIO; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; +import org.mapdb.ser.StringDelta2Serializer.ByteArrayKeys; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by jan on 2/29/16. + */ +public class ByteArrayDelta2Serializer implements GroupSerializer { + + + @Override + public int valueArraySearch(ByteArrayKeys keys, byte[] key) { + Object[] v = valueArrayToArray(keys); + return Arrays.binarySearch(v, key, (Comparator)this); + } + + @Override + public int valueArraySearch(ByteArrayKeys keys, byte[] key, Comparator comparator) { + Object[] v = valueArrayToArray(keys); + return Arrays.binarySearch(v, key, comparator); + } + + @Override + public void valueArraySerialize(DataOutput2 out, ByteArrayKeys keys2) { + ByteArrayKeys keys = (ByteArrayKeys) keys2; + int offset = 0; + //write sizes + for(int o:keys.offset){ + out.packInt(o-offset); + offset = o; + } + //$DELAY$ + //find and write common prefix + int prefixLen = keys.commonPrefixLen(); + out.packInt(prefixLen); + out.write(keys.array,0,prefixLen); + //$DELAY$ + //write suffixes + offset = prefixLen; + for(int o:keys.offset){ + out.write(keys.array, offset, o-offset); + offset = o+prefixLen; + } + } + + @Override + public ByteArrayKeys valueArrayDeserialize(DataInput2 in, int size) { + //read data sizes + int[] offsets = new int[size]; + int old=0; + for(int i=0;i { + + @Override + public void serialize(DataOutput2 out, byte[] value) { + out.write(value); + } + + @Override + public byte[] deserialize(@NotNull DataInput2 input) { + int avail = input.available(); + byte[] ret = new byte[avail]; + input.readFully(ret, 0, avail); + return ret; + } + + @Nullable + @Override + public Class serializedType() { + return null; + } + + @Override + public byte[] deserialize(DataInput2 in, int available) { + byte[] ret = new byte[available]; + in.readFully(ret); + return ret; + } + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public boolean equals(byte[] a1, byte[] a2) { + return Arrays.equals(a1, a2); + } + + @Override + public int hashCode(byte[] bytes, int seed) { + return Serializers.BYTE_ARRAY.hashCode(bytes, seed); + } + + @Override + public int compare(byte[] o1, byte[] o2) { + if (o1 == o2) return 0; + final int len = Math.min(o1.length, o2.length); + for (int i = 0; i < len; i++) { + int b1 = o1[i] & 0xFF; + int b2 = o2[i] & 0xFF; + if (b1 != b2) + return b1 - b2; + } + return o1.length - o2.length; + } + +} diff --git a/src/main/java/org/mapdb/ser/ByteArraySerializer.java b/src/main/java/org/mapdb/ser/ByteArraySerializer.java new file mode 100644 index 000000000..5f9a3c4ed --- /dev/null +++ b/src/main/java/org/mapdb/ser/ByteArraySerializer.java @@ -0,0 +1,172 @@ +package org.mapdb.ser; + +import net.jpountz.xxhash.XXHash32; +import net.jpountz.xxhash.XXHashFactory; +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by jan on 2/28/16. + */ +public class ByteArraySerializer implements GroupSerializer { + + //TODO thread safe? + private static final XXHash32 HASHER = XXHashFactory.fastestInstance().hash32(); + + @Override + public void serialize(DataOutput2 out, byte[] value) { + out.packInt(value.length); + out.write(value); + } + + @Override + public byte[] deserialize(DataInput2 in) { + int size = in.unpackInt(); + byte[] ret = new byte[size]; + in.readFully(ret); + return ret; + } + + @Nullable + @Override + public Class serializedType() { + return byte[].class; + } + + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public boolean equals(byte[] a1, byte[] a2) { + return Arrays.equals(a1, a2); + } + + public int hashCode(byte[] bytes, int seed) { + return HASHER.hash(bytes, 0, bytes.length, seed); + } + + @Override + public int compare(byte[] o1, byte[] o2) { + if (o1 == o2) return 0; + final int len = Math.min(o1.length, o2.length); + for (int i = 0; i < len; i++) { + int b1 = o1[i] & 0xFF; + int b2 = o2[i] & 0xFF; + if (b1 != b2) + return b1 - b2; + } + return o1.length - o2.length; + } + + @Override + public int valueArraySearch(byte[][] keys, byte[] key) { + return Arrays.binarySearch((byte[][])keys, key, Serializers.BYTE_ARRAY); + } + + @Override + public int valueArraySearch(byte[][] keys, byte[] key, Comparator comparator) { + //TODO PERF optimize search + Object[] v = valueArrayToArray(keys); + return Arrays.binarySearch(v, key, comparator); + } + + @Override + public void valueArraySerialize(DataOutput2 out, byte[][] vals) { + byte[][] vals2 = (byte[][]) vals; + out.packInt(vals2.length); + for(byte[]b:vals2){ + Serializers.BYTE_ARRAY.serialize(out, b); + } + } + + @Override + public byte[][] valueArrayDeserialize(DataInput2 in, int size) { + int s = in.unpackInt(); + byte[][] ret = new byte[s][]; + for(int i=0;i { + + //TODO use byte[] group serializer + + @Override + public void serialize(DataOutput2 out, Byte value) { + out.writeByte(value); + } + + @Override + public Byte deserialize(DataInput2 in) { + return in.readByte(); + } + + @Nullable + @Override + public Class serializedType() { + return Byte.class; + } + + //TODO value array operations + + @Override + public int fixedSize() { + return 1; + } + + @Override + public boolean isTrusted() { + return true; + } + +} diff --git a/src/main/java/org/mapdb/ser/CharArraySerializer.java b/src/main/java/org/mapdb/ser/CharArraySerializer.java new file mode 100644 index 000000000..f38ce19fe --- /dev/null +++ b/src/main/java/org/mapdb/ser/CharArraySerializer.java @@ -0,0 +1,86 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; + +/** + * Created by jan on 2/28/16. + */ +public class CharArraySerializer extends DefaultGroupSerializer { + + @Override + public void serialize(DataOutput2 out, char[] value) { + out.packInt(value.length); + for (char c : value) { + out.writeChar(c); + } + } + + @Override + public char[] deserialize(DataInput2 in) { + final int size = in.unpackInt(); + char[] ret = new char[size]; + for (int i = 0; i < size; i++) { + ret[i] = in.readChar(); + } + return ret; + } + + @Nullable + @Override + public Class serializedType() { + return char[].class; + } + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public boolean equals(char[] a1, char[] a2) { + return Arrays.equals(a1, a2); + } + + @Override + public int hashCode(char[] chars, int seed) { + int res = 0; + for (char c : chars) { + res = (res + c) * -1640531527 ; + } + return res; + } + + @Override + public int compare(char[] o1, char[] o2) { + final int len = Math.min(o1.length, o2.length); + for (int i = 0; i < len; i++) { + int b1 = o1[i]; + int b2 = o2[i]; + if (b1 != b2) + return b1 - b2; + } + return SerializerUtils.compareInt(o1.length, o2.length); + } + + @Override + public char[] nextValue(char[] value) { + value = value.clone(); + + for (int i = value.length-1; ;i--) { + char b1 = value[i]; + if(b1==Character.MAX_VALUE){ + if(i==0) + return null; + value[i]=Character.MIN_VALUE; + continue; + } + value[i] = (char) (b1+1); + return value; + } + } +} diff --git a/src/main/java/org/mapdb/ser/CharSerializer.java b/src/main/java/org/mapdb/ser/CharSerializer.java new file mode 100644 index 000000000..69c08d7cb --- /dev/null +++ b/src/main/java/org/mapdb/ser/CharSerializer.java @@ -0,0 +1,40 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; + +/** + * Created by jan on 2/28/16. + */ +public class CharSerializer extends DefaultGroupSerializer { + @Override + public void serialize(DataOutput2 out, Character value) { + out.writeChar(value.charValue()); + } + + @Override + public Character deserialize(DataInput2 in) { + return in.readChar(); + } + + @Nullable + @Override + public Class serializedType() { + return Character.class; + } + + @Override + public int fixedSize() { + return 2; + } + + @Override + public boolean isTrusted() { + return true; + } + + //TODO value array +} diff --git a/src/main/java/org/mapdb/ser/ClassSerializer.java b/src/main/java/org/mapdb/ser/ClassSerializer.java new file mode 100644 index 000000000..018ed421d --- /dev/null +++ b/src/main/java/org/mapdb/ser/ClassSerializer.java @@ -0,0 +1,61 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.DBException; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; + +/** + * Serialier for class. It takes a class loader as constructor param, by default it uses + * {@code Thread.currentThread().getContextClassLoader()} + */ +public class ClassSerializer extends DefaultGroupSerializer { + + protected final ClassLoader classLoader; + + public ClassSerializer(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + public ClassSerializer(){ + this(Thread.currentThread().getContextClassLoader()); + } + + @Override + public void serialize(DataOutput2 out, Class value) { + out.writeUTF(value.getName()); + } + + @Override + public Class deserialize(DataInput2 in) { + try { + return classLoader.loadClass(in.readUTF()); + } catch (ClassNotFoundException e) { + throw new DBException.SerializationError(e); + } + } + + @Nullable + @Override + public Class serializedType() { + return Class.class; + } + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public boolean equals(Class a1, Class a2) { + return a1 == a2 || (a1.toString().equals(a2.toString())); + } + + @Override + public int hashCode(Class aClass, int seed) { + //class does not override identity hash code + return aClass.toString().hashCode(); + } +} diff --git a/src/main/java/org/mapdb/ser/DateSerializer.java b/src/main/java/org/mapdb/ser/DateSerializer.java new file mode 100644 index 000000000..ae004e0c5 --- /dev/null +++ b/src/main/java/org/mapdb/ser/DateSerializer.java @@ -0,0 +1,50 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Date; + +/** + * Created by jan on 2/28/16. + */ +public class DateSerializer extends EightByteSerializer { + + @Override + public void serialize(DataOutput2 out, Date value) { + out.writeLong(value.getTime()); + } + + @Override + public Date deserialize(DataInput2 in) { + return new Date(in.readLong()); + } + + @Nullable + @Override + public Class serializedType() { + return Date.class; + } + + @Override + protected Date unpack(long l) { + return new Date(l); + } + + @Override + protected long pack(Date l) { + return l.getTime(); + } + + @Override + final public int valueArraySearch(long[] keys, Date key) { + //TODO valueArraySearch versus comparator test + long time = key.getTime(); + return Arrays.binarySearch((long[])keys, time); + } + + +} diff --git a/src/main/java/org/mapdb/ser/DefaultGroupSerializer.java b/src/main/java/org/mapdb/ser/DefaultGroupSerializer.java new file mode 100644 index 000000000..c2780e42b --- /dev/null +++ b/src/main/java/org/mapdb/ser/DefaultGroupSerializer.java @@ -0,0 +1,80 @@ +package org.mapdb.ser; + +import org.mapdb.io.DataIO; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by jan on 2/29/16. + */ +public abstract class DefaultGroupSerializer implements GroupSerializer { + + + @Override public void valueArraySerialize(DataOutput2 out, Object[] vals) { + for(Object o:vals){ + serialize(out, (A)o); + } + } + + @Override public Object[] valueArrayDeserialize(DataInput2 in, int size) { + Object[] ret = new Object[size]; + for(int i=0;i)this); + } + + @Override public Object[] valueArrayToArray(Object[] vals){ + return (Object[]) vals; + } + @Override public int valueArraySearch(Object[] keys, A key, Comparator comparator){ + if(comparator==this) + return valueArraySearch(keys, key); + return Arrays.binarySearch(keys, key, comparator); + } + + +} diff --git a/src/main/java/org/mapdb/ser/DoubleArraySerializer.java b/src/main/java/org/mapdb/ser/DoubleArraySerializer.java new file mode 100644 index 000000000..e3408eac5 --- /dev/null +++ b/src/main/java/org/mapdb/ser/DoubleArraySerializer.java @@ -0,0 +1,74 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; + +/** + * Created by jan on 2/28/16. + */ +public class DoubleArraySerializer extends DefaultGroupSerializer { + + @Override + public void serialize(DataOutput2 out, double[] value) { + out.packInt(value.length); + for (double c : value) { + out.writeDouble(c); + } + } + + @Override + public double[] deserialize(DataInput2 in) { + final int size = in.unpackInt(); + double[] ret = new double[size]; + for (int i = 0; i < size; i++) { + ret[i] = in.readDouble(); + } + return ret; + } + + @Nullable + @Override + public Class serializedType() { + return double[].class; + } + + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public boolean equals(double[] a1, double[] a2) { + return Arrays.equals(a1, a2); + } + + @Override + public int hashCode(double[] bytes, int seed) { + for (double element : bytes) { + long bits = Double.doubleToLongBits(element); + seed = (-1640531527) * seed + (int) (bits ^ (bits >>> 32)); + } + return seed; + } + + @Override + public int compare(double[] o1, double[] o2) { + if (o1 == o2) return 0; + final int len = Math.min(o1.length, o2.length); + for (int i = 0; i < len; i++) { + if (o1[i] == o2[i]) + continue; + if (o1[i] > o2[i]) + return 1; + return -1; + } + return SerializerUtils.compareInt(o1.length, o2.length); + } + + +} diff --git a/src/main/java/org/mapdb/ser/DoubleSerializer.java b/src/main/java/org/mapdb/ser/DoubleSerializer.java new file mode 100644 index 000000000..aaf69a5b9 --- /dev/null +++ b/src/main/java/org/mapdb/ser/DoubleSerializer.java @@ -0,0 +1,46 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; + +/** + * Created by jan on 2/28/16. + */ +public class DoubleSerializer extends EightByteSerializer { + @Override + protected Double unpack(long l) { + return new Double(Double.longBitsToDouble(l)); + } + + @Override + protected long pack(Double l) { + return Double.doubleToLongBits(l); + } + + @Override + public int valueArraySearch(long[] keys, Double key) { + //TODO PERF this can be optimized, but must take care of NaN + return Arrays.binarySearch(valueArrayToArray(keys), key); + } + + @Override + public void serialize(DataOutput2 out, Double value) { + out.writeDouble(value); + } + + @Override + public Double deserialize(DataInput2 in) { + return new Double(in.readDouble()); + } + + @Nullable + @Override + public Class serializedType() { + return Double.class; + } + +} diff --git a/src/main/java/org/mapdb/ser/EightByteSerializer.java b/src/main/java/org/mapdb/ser/EightByteSerializer.java new file mode 100644 index 000000000..619232966 --- /dev/null +++ b/src/main/java/org/mapdb/ser/EightByteSerializer.java @@ -0,0 +1,134 @@ +package org.mapdb.ser; + +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +public abstract class EightByteSerializer implements GroupSerializer { + + protected abstract E unpack(long l); + protected abstract long pack(E l); + + @Override + public E valueArrayGet(long[] vals, int pos){ + return unpack(((long[]) vals)[pos]); + } + + + @Override + public int valueArraySize(long[] vals){ + return ((long[])vals).length; + } + + @Override + public long[] valueArrayEmpty(){ + return new long[0]; + } + + @Override + public long[] valueArrayPut(long[] vals, int pos, E newValue) { + + long[] array = (long[]) vals; + final long[] ret = Arrays.copyOf(array, array.length+1); + if(pos>> 1; + int compare = comparator.compare(key, unpack(array[mid])); + + if (compare == 0) + return mid; + else if (compare < 0) + hi = mid - 1; + else + lo = mid + 1; + } + return -(lo + 1); + } + +} diff --git a/src/main/java/org/mapdb/ser/FloatArraySerializer.java b/src/main/java/org/mapdb/ser/FloatArraySerializer.java new file mode 100644 index 000000000..3b43bf9c8 --- /dev/null +++ b/src/main/java/org/mapdb/ser/FloatArraySerializer.java @@ -0,0 +1,67 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; + +/** + * Created by jan on 2/28/16. + */ +public class FloatArraySerializer extends DefaultGroupSerializer { + @Override + public void serialize(DataOutput2 out, float[] value) { + out.packInt(value.length); + for (float v : value) { + out.writeFloat(v); + } + } + + @Override + public float[] deserialize(DataInput2 in) { + float[] ret = new float[in.unpackInt()]; + for (int i = 0; i < ret.length; i++) { + ret[i] = in.readFloat(); + } + return ret; + } + + @Nullable + @Override + public Class serializedType() { + return float[].class; + } + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public boolean equals(float[] a1, float[] a2) { + return Arrays.equals(a1, a2); + } + + @Override + public int hashCode(float[] floats, int seed) { + for (float element : floats) + seed = (-1640531527) * seed + Float.floatToIntBits(element); + return seed; + } + + @Override + public int compare(float[] o1, float[] o2) { + if (o1 == o2) return 0; + final int len = Math.min(o1.length, o2.length); + for (int i = 0; i < len; i++) { + if (o1[i] == o2[i]) + continue; + if (o1[i] > o2[i]) + return 1; + return -1; + } + return SerializerUtils.compareInt(o1.length, o2.length); + } +} diff --git a/src/main/java/org/mapdb/ser/FloatSerializer.java b/src/main/java/org/mapdb/ser/FloatSerializer.java new file mode 100644 index 000000000..6b5543d08 --- /dev/null +++ b/src/main/java/org/mapdb/ser/FloatSerializer.java @@ -0,0 +1,50 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; + +/** + * Created by jan on 2/28/16. + */ +public class FloatSerializer extends FourByteSerializer { + + @Override + protected Float unpack(int l) { + return new Float(Float.intBitsToFloat(l)); + } + + @Override + protected int pack(Float l) { + return Float.floatToIntBits(l); + } + + + @Override + public void serialize(DataOutput2 out, Float value) { + out.writeFloat(value); + } + + @Override + public Float deserialize(DataInput2 in) { + return new Float(in.readFloat()); + } + + @Nullable + @Override + public Class serializedType() { + return Float.class; + } + + + @Override + public int valueArraySearch(int[] keys, Float key) { + //TODO PERF this can be optimized, but must take care of NaN + return Arrays.binarySearch(valueArrayToArray(keys), key); + } + + +} diff --git a/src/main/java/org/mapdb/ser/FourByteSerializer.java b/src/main/java/org/mapdb/ser/FourByteSerializer.java new file mode 100644 index 000000000..dda7302d3 --- /dev/null +++ b/src/main/java/org/mapdb/ser/FourByteSerializer.java @@ -0,0 +1,133 @@ +package org.mapdb.ser; + +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by jan on 2/28/16. + */ +public abstract class FourByteSerializer implements GroupSerializer { + + protected abstract E unpack(int l); + + protected abstract int pack(E l); + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public int fixedSize() { + return 4; + } + + @Override + public E valueArrayGet(int[] vals, int pos) { + return unpack(((int[]) vals)[pos]); + } + + @Override + public int valueArraySize(int[] vals) { + return ((int[]) vals).length; + } + + @Override + public int[] valueArrayEmpty() { + return new int[0]; + } + + @Override + public int[] valueArrayPut(int[] vals, int pos, E newValue) { + + final int[] ret = Arrays.copyOf(vals, vals.length + 1); + if (pos < vals.length) { + System.arraycopy(vals, pos, ret, pos + 1, vals.length - pos); + } + ret[pos] = pack(newValue); + return ret; + } + + @Override + public int[] valueArrayUpdateVal(int[] vals, int pos, E newValue) { + int[] vals2 = ((int[]) vals).clone(); + vals2[pos] = pack(newValue); + return vals2; + } + + @Override + public int[] valueArrayFromArray(Object[] objects) { + int[] ret = new int[objects.length]; + int pos = 0; + + for (Object o : objects) { + ret[pos++] = pack((E) o); + } + + return ret; + } + + @Override + public int[] valueArrayCopyOfRange(int[] vals, int from, int to) { + return Arrays.copyOfRange((int[]) vals, from, to); + } + + @Override + public int[] valueArrayDeleteValue(int[] vals, int pos) { + int[] valsOrig = (int[]) vals; + int[] vals2 = new int[valsOrig.length - 1]; + System.arraycopy(vals, 0, vals2, 0, pos - 1); + System.arraycopy(vals, pos, vals2, pos - 1, vals2.length - (pos - 1)); + return vals2; + } + + + @Override + public void valueArraySerialize(DataOutput2 out, int[] vals) { + for (int o : (int[]) vals) { + out.writeInt(o); + } + } + + @Override + public int[] valueArrayDeserialize(DataInput2 in, int size) { + int[] ret = new int[size]; + for (int i = 0; i < size; i++) { + ret[i] = in.readInt(); + } + return ret; + } + + @Override + final public int valueArraySearch(int[] keys, E key, Comparator comparator) { + if (comparator == this) + return valueArraySearch(keys, key); + + int lo = 0; + int hi = keys.length - 1; + + while (lo <= hi) { + int mid = (lo + hi) >>> 1; + int compare = comparator.compare(key, unpack(keys[mid])); + + if (compare == 0) + return mid; + else if (compare < 0) + hi = mid - 1; + else + lo = mid + 1; + } + return -(lo + 1); + } + + @Override + public E valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { + input.skipBytes(pos*4); + return unpack(input.readInt()); + } + +} diff --git a/src/main/java/org/mapdb/ser/GroupSerializer.java b/src/main/java/org/mapdb/ser/GroupSerializer.java new file mode 100644 index 000000000..9400fa61a --- /dev/null +++ b/src/main/java/org/mapdb/ser/GroupSerializer.java @@ -0,0 +1,80 @@ +package org.mapdb.ser; + +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Comparator; + +/** + * Created by jan on 2/29/16. + */ +public interface GroupSerializer extends Serializer { + + default A valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { + G keys = valueArrayDeserialize(input, keysLen); + return valueArrayGet(keys, pos); +// A a=null; +// while(pos-- >= 0){ +// a = deserialize(input, -1); +// } +// return a; + } + + + + default int valueArrayBinarySearch(A key, DataInput2 input, int keysLen, Comparator comparator) { + G keys = valueArrayDeserialize(input, keysLen); + return valueArraySearch(keys, key, comparator); +// for(int pos=0; pos { + + @Override + public void serialize(DataOutput2 out, int[] value) { + out.packInt(value.length); + for (int c : value) { + out.writeInt(c); + } + } + + @Override + public int[] deserialize(DataInput2 in) { + final int size = in.unpackInt(); + int[] ret = new int[size]; + for (int i = 0; i < size; i++) { + ret[i] = in.readInt(); + } + return ret; + } + + @Nullable + @Override + public Class serializedType() { + return int[].class; + } + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public boolean equals(int[] a1, int[] a2) { + return Arrays.equals(a1, a2); + } + + @Override + public int hashCode(int[] bytes, int seed) { + for (int i : bytes) { + seed = (-1640531527) * seed + i; + } + return seed; + } + + @Override + public int compare(int[] o1, int[] o2) { + if (o1 == o2) return 0; + final int len = Math.min(o1.length, o2.length); + for (int i = 0; i < len; i++) { + if (o1[i] == o2[i]) + continue; + if (o1[i] > o2[i]) + return 1; + return -1; + } + return SerializerUtils.compareInt(o1.length, o2.length); + } + + @Override + public int[] nextValue(int[] value) { + value = value.clone(); + + for (int i = value.length-1; ;i--) { + int b1 = value[i]; + if(b1==Integer.MAX_VALUE){ + if(i==0) + return null; + value[i]=Integer.MIN_VALUE; + continue; + } + value[i] = b1+1; + return value; + } + } + +} diff --git a/src/main/java/org/mapdb/ser/IntegerDeltaSerializer.java b/src/main/java/org/mapdb/ser/IntegerDeltaSerializer.java new file mode 100644 index 000000000..d903fb8b3 --- /dev/null +++ b/src/main/java/org/mapdb/ser/IntegerDeltaSerializer.java @@ -0,0 +1,86 @@ +package org.mapdb.ser; + +import org.mapdb.CC; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Comparator; + +/** + * Created by jan on 2/28/16. + */ +public class IntegerDeltaSerializer extends IntegerSerializer { + @Override + public void serialize(DataOutput2 out, Integer value) { + out.packInt(value); + } + + @Override + public Integer deserialize(DataInput2 in, int available) { + return new Integer(in.unpackInt()); + } + + @Override + public void valueArraySerialize(DataOutput2 out, int[] vals) { + int[] keys = (int[]) vals; + int prev = keys[0]; + out.packInt(prev); + for (int i = 1; i < keys.length; i++) { + int curr = keys[i]; + //$DELAY$ + out.packInt(curr - prev); + if (CC.ASSERT && curr < prev) + throw new AssertionError("not sorted"); + prev = curr; + } + } + + @Override + public int[] valueArrayDeserialize(DataInput2 in, int size) { + int[] ret = new int[size]; + int prev = 0; + for (int i = 0; i < size; i++) { + //$DELAY$ + prev += in.unpackInt(); + ret[i] = prev; + } + return ret; + } + + + @Override + public Integer valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { + int a = 0; + while (pos-- >= 0) { + a += input.unpackInt(); + } + return a; + } + + + @Override + public int valueArrayBinarySearch(Integer key, DataInput2 input, int keysLen, Comparator comparator) { + if (comparator != this) + return super.valueArrayBinarySearch(key, input, keysLen, comparator); + int key2 = key; + int from = 0; + for (int pos = 0; pos < keysLen; pos++) { + from += input.unpackInt(); + + if (key2 <= from) { + input.unpackLongSkip(keysLen-pos-1); + return (key2 == from) ? pos : -(pos + 1); + } + } + + //not found + return -(keysLen + 1); + } + + @Override + public int fixedSize() { + return -1; + } + +} diff --git a/src/main/java/org/mapdb/ser/IntegerPackedSerializer.java b/src/main/java/org/mapdb/ser/IntegerPackedSerializer.java new file mode 100644 index 000000000..63c888da3 --- /dev/null +++ b/src/main/java/org/mapdb/ser/IntegerPackedSerializer.java @@ -0,0 +1,67 @@ +package org.mapdb.ser; + +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Comparator; + +/** + * Created by jan on 2/28/16. + */ +public class IntegerPackedSerializer extends IntegerSerializer { + @Override + public void serialize(DataOutput2 out, Integer value) { + out.packInt(value); + } + + @Override + public Integer deserialize(DataInput2 in, int available) { + return new Integer(in.unpackInt()); + } + + @Override + public void valueArraySerialize(DataOutput2 out, int[] vals) { + for (int o : (int[])vals) { + out.packInt(o); //TODO packIntBigger() + } + } + + @Override + public int[] valueArrayDeserialize(DataInput2 in, int size) { + int[] ret = new int[size]; + //TODO int arrays +// in.unpackIntArray(ret, 0, size); + return ret; + } + + @Override + public int fixedSize() { + return -1; + } + + @Override + public int valueArrayBinarySearch(Integer key, DataInput2 input, int keysLen, Comparator comparator) { + if (comparator != this) + return super.valueArrayBinarySearch(key, input, keysLen, comparator); + int key2 = key; + for (int pos = 0; pos < keysLen; pos++) { + int from = input.unpackInt(); + + if (key2 <= from) { + input.unpackLongSkip(keysLen-pos-1); + return (key2 == from) ? pos : -(pos + 1); + } + } + + //not found + return -(keysLen + 1); + } + + @Override + public Integer valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { + input.unpackLongSkip(pos); + return input.unpackInt(); + } + +} diff --git a/src/main/java/org/mapdb/ser/IntegerSerializer.java b/src/main/java/org/mapdb/ser/IntegerSerializer.java new file mode 100644 index 000000000..22610ae83 --- /dev/null +++ b/src/main/java/org/mapdb/ser/IntegerSerializer.java @@ -0,0 +1,63 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +public class IntegerSerializer extends FourByteSerializer { + + + @Override + public void serialize(DataOutput2 out, Integer value) { + out.writeInt(value); + } + + @Override + public Integer deserialize(DataInput2 in) { + return new Integer(in.readInt()); + } + + @Nullable + @Override + public Class serializedType() { + return Integer.class; + } + + @Override + protected Integer unpack(int l) { + return new Integer(l); + } + + @Override + protected int pack(Integer l) { + return l; + } + + @Override + public int valueArraySearch(int[] keys, Integer key) { + return Arrays.binarySearch((int[]) keys, key); + } + + + @Override + public int valueArrayBinarySearch(Integer key, DataInput2 input, int keysLen, Comparator comparator) { + if (comparator != this) + return super.valueArrayBinarySearch(key, input, keysLen, comparator); + final int key2 = key; + for (int pos = 0; pos < keysLen; pos++) { + int from = input.readInt(); + + if (key2 <= from) { + input.skipBytes((keysLen-pos-1)*4); + return (key2 == from) ? pos : -(pos + 1); + } + } + + //not found + return -(keysLen + 1); + } +} diff --git a/src/main/java/org/mapdb/ser/JavaSerializer.java b/src/main/java/org/mapdb/ser/JavaSerializer.java new file mode 100644 index 000000000..faa9de59d --- /dev/null +++ b/src/main/java/org/mapdb/ser/JavaSerializer.java @@ -0,0 +1,71 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.CC; +import org.mapdb.DBException; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataInputToStream; +import org.mapdb.io.DataOutput2; + +import java.io.*; + +/** + * Created by jan on 2/28/16. + */ +public class JavaSerializer extends DefaultGroupSerializer { + @Override + public void serialize(DataOutput2 out, E value) { + ObjectOutputStream out2 = null; + try { + out2 = new ObjectOutputStream((OutputStream) out); + out2.writeObject(value); + out2.flush(); + } catch (IOException e) { + throw new IOError(e); + } + } + + @Override + public E deserialize(DataInput2 in) { + try { + ObjectInputStream in2 = new ObjectInputStream(new DataInputToStream(in)); + return (E) in2.readObject(); + } catch (ClassNotFoundException e) { + throw new DBException.SerializationError(e); + } catch (IOException e) { + throw new IOError(e); + } + } + + @Nullable + @Override + public Class serializedType() { + return Object.class; + } + + @Override + public Object[] valueArrayDeserialize(DataInput2 in, int size) { + try { + ObjectInputStream in2 = new ObjectInputStream(new DataInputToStream(in)); + Object[] ret = (Object[]) in2.readObject(); + if(CC.PARANOID && size!=valueArraySize(ret)) + throw new AssertionError(); + return ret; + } catch (ClassNotFoundException e) { + throw new DBException.SerializationError(e); + } catch (IOException e) { + throw new IOError(e); + } + } + + @Override + public void valueArraySerialize(DataOutput2 out, Object[] vals) { + try{ + ObjectOutputStream out2 = new ObjectOutputStream((OutputStream) out); + out2.writeObject(vals); + out2.flush(); + } catch (IOException e) { + throw new IOError(e); + } + } +} diff --git a/src/main/java/org/mapdb/ser/LongArraySerializer.java b/src/main/java/org/mapdb/ser/LongArraySerializer.java new file mode 100644 index 000000000..8cff38ebd --- /dev/null +++ b/src/main/java/org/mapdb/ser/LongArraySerializer.java @@ -0,0 +1,89 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; + +/** + * Created by jan on 2/28/16. + */ +public class LongArraySerializer extends DefaultGroupSerializer { + + @Override + public void serialize(DataOutput2 out, long[] value) { + out.packInt(value.length); + for (long c : value) { + out.writeLong(c); + } + } + + @Override + public long[] deserialize(DataInput2 in) { + final int size = in.unpackInt(); + long[] ret = new long[size]; + for (int i = 0; i < size; i++) { + ret[i] = in.readLong(); + } + return ret; + } + + @Nullable + @Override + public Class serializedType() { + return long[].class; + } + + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public boolean equals(long[] a1, long[] a2) { + return Arrays.equals(a1, a2); + } + + @Override + public int hashCode(long[] bytes, int seed) { + for (long element : bytes) { + int elementHash = (int) (element ^ (element >>> 32)); + seed = (-1640531527) * seed + elementHash; + } + return seed; + } + + @Override + public int compare(long[] o1, long[] o2) { + if (o1 == o2) return 0; + final int len = Math.min(o1.length, o2.length); + for (int i = 0; i < len; i++) { + if (o1[i] == o2[i]) + continue; + if (o1[i] > o2[i]) + return 1; + return -1; + } + return SerializerUtils.compareInt(o1.length, o2.length); + } + + @Override + public long[] nextValue(long[] value) { + value = value.clone(); + + for (int i = value.length-1; ;i--) { + long b1 = value[i]; + if(b1==Long.MAX_VALUE){ + if(i==0) + return null; + value[i]=Long.MIN_VALUE; + continue; + } + value[i] = b1+1L; + return value; + } + } +} diff --git a/src/main/java/org/mapdb/ser/LongDeltaSerializer.java b/src/main/java/org/mapdb/ser/LongDeltaSerializer.java new file mode 100644 index 000000000..75102adfc --- /dev/null +++ b/src/main/java/org/mapdb/ser/LongDeltaSerializer.java @@ -0,0 +1,80 @@ +package org.mapdb.ser; + +import org.mapdb.CC; +import org.mapdb.DBException; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Comparator; + +/** + * Created by jan on 2/28/16. + */ +public class LongDeltaSerializer extends LongSerializer { + @Override + public void serialize(DataOutput2 out, Long value) { + out.writePackedLong(value); + } + + @Override + public Long deserialize(DataInput2 in, int available) { + return new Long(in.readPackedLong()); + } + + @Override + public void valueArraySerialize(DataOutput2 out, long[] vals) { + long[] keys = (long[]) vals; + long prev = keys[0]; + out.writePackedLong(prev); + for (int i = 1; i < keys.length; i++) { + long curr = keys[i]; + //$DELAY$ + out.writePackedLong(curr - prev); + if (CC.ASSERT && curr < prev) + throw new AssertionError("not sorted"); + prev = curr; + } + } + + @Override + public long[] valueArrayDeserialize(DataInput2 in, int size) { + throw new DBException.TODO("delta packing"); +// return in.unpackLongArrayDeltaCompression(size); + } + + + @Override + public Long valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { + long a = 0; + while (pos-- >= 0) { + a += input.readPackedLong(); + } + return a; + } + + @Override + public int valueArrayBinarySearch(Long key, DataInput2 input, int keysLen, Comparator comparator) { + if (comparator != this) + return super.valueArrayBinarySearch(key, input, keysLen, comparator); + long key2 = key; + long from = 0; + for (int pos = 0; pos < keysLen; pos++) { + from += input.readPackedLong(); + + if (key2 <= from) { + input.unpackLongSkip(keysLen-pos-1); + return (key2 == from) ? pos : -(pos + 1); + } + } + + //not found + return -(keysLen + 1); + } + + + @Override + public int fixedSize() { + return -1; + } +} diff --git a/src/main/java/org/mapdb/ser/LongPackedSerializer.java b/src/main/java/org/mapdb/ser/LongPackedSerializer.java new file mode 100644 index 000000000..20708dbb9 --- /dev/null +++ b/src/main/java/org/mapdb/ser/LongPackedSerializer.java @@ -0,0 +1,70 @@ +package org.mapdb.ser; + +import org.mapdb.DBException; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Comparator; + +/** + * Created by jan on 2/28/16. + */ +public class LongPackedSerializer extends LongSerializer { + @Override + public void serialize(DataOutput2 out, Long value) { + out.writePackedLong(value); + } + + @Override + public Long deserialize(DataInput2 in, int available) { + return new Long(in.readPackedLong()); + } + + @Override + public void valueArraySerialize(DataOutput2 out, long[] vals) { + for (long o : (long[])vals) { + out.writePackedLong(o); + } + } + + @Override + public long[] valueArrayDeserialize(DataInput2 in, int size) { + long[] ret = new long[size]; + throw new DBException.TODO("packed long"); +// in.unpackLongArray(ret, 0, size); +// return ret; + } + + @Override + public int fixedSize() { + return -1; + } + + @Override + public int valueArrayBinarySearch(Long key, DataInput2 input, int keysLen, Comparator comparator) { + if (comparator != this) + return super.valueArrayBinarySearch(key, input, keysLen, comparator); + long key2 = key; + for (int pos = 0; pos < keysLen; pos++) { + long from = input.readPackedLong(); + + if (key2 <= from) { + input.unpackLongSkip(keysLen - pos - 1); + return (key2 == from) ? pos : -(pos + 1); + } + } + + //not found + return -(keysLen + 1); + } + + @Override + public Long valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { + input.unpackLongSkip(pos); + return input.readPackedLong(); + } + + + +} diff --git a/src/main/java/org/mapdb/ser/LongSerializer.java b/src/main/java/org/mapdb/ser/LongSerializer.java new file mode 100644 index 000000000..925e1f800 --- /dev/null +++ b/src/main/java/org/mapdb/ser/LongSerializer.java @@ -0,0 +1,67 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by jan on 2/28/16. + */ +public class LongSerializer extends EightByteSerializer { + + @Override + public void serialize(DataOutput2 out, Long value) { + out.writeLong(value); + } + + @Override + public Long deserialize(DataInput2 in) { + return new Long(in.readLong()); + } + + @Nullable + @Override + public Class serializedType() { + return long[].class; + } + + + @Override + protected Long unpack(long l) { + return new Long(l); + } + + @Override + protected long pack(Long l) { + return l.longValue(); + } + + @Override + public int valueArraySearch(long[] keys, Long key) { + return Arrays.binarySearch((long[])keys, key); + } + + + @Override + public int valueArrayBinarySearch(Long key, DataInput2 input, int keysLen, Comparator comparator) { + if (comparator != this) + return super.valueArrayBinarySearch(key, input, keysLen, comparator); + long key2 = key; + for (int pos = 0; pos < keysLen; pos++) { + long from = input.readLong(); + + if (key2 <= from) { + input.skipBytes((keysLen-pos-1)*8); + return (key2 == from) ? pos : -(pos + 1); + } + } + + //not found + return -(keysLen + 1); + } + +} diff --git a/src/main/java/org/mapdb/ser/RecidArraySerializer.java b/src/main/java/org/mapdb/ser/RecidArraySerializer.java new file mode 100644 index 000000000..8fd63e8aa --- /dev/null +++ b/src/main/java/org/mapdb/ser/RecidArraySerializer.java @@ -0,0 +1,33 @@ +package org.mapdb.ser; + +import org.mapdb.io.DataIO; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; + +/** + * Created by jan on 2/28/16. + */ +public class RecidArraySerializer extends LongArraySerializer{ + + @Override + public void serialize(DataOutput2 out, long[] value) { + out.packInt(value.length); + for (long recid : value) { + DataIO.packRecid(out, recid); + } + } + + @Override + public long[] deserialize(DataInput2 in, int available) { + int size = in.unpackInt(); + long[] ret = new long[size]; + for (int i = 0; i < size; i++) { + ret[i] = DataIO.unpackRecid(in); + } + return ret; + } + + +} diff --git a/src/main/java/org/mapdb/ser/RecidSerializer.java b/src/main/java/org/mapdb/ser/RecidSerializer.java new file mode 100644 index 000000000..0e783d1e8 --- /dev/null +++ b/src/main/java/org/mapdb/ser/RecidSerializer.java @@ -0,0 +1,79 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataIO; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; + +/** + * Created by jan on 2/28/16. + */ +public class RecidSerializer extends EightByteSerializer { + + @Override + public void serialize(DataOutput2 out, Long value) { + DataIO.packRecid(out, value); + } + + @Override + public Long deserialize(DataInput2 in) { + return new Long(DataIO.unpackRecid(in)); + } + + @Nullable + @Override + public Class serializedType() { + return Long.class; + } + + @Override + public int fixedSize() { + return -1; + } + + @Override + protected Long unpack(long l) { + return new Long(l); + } + + @Override + protected long pack(Long l) { + return l; + } + + @Override + public boolean isTrusted() { + return true; + } + + + @Override + public int valueArraySearch(long[] keys, Long key) { + return Arrays.binarySearch((long[])keys, key); + } + + @Override + public void valueArraySerialize(DataOutput2 out, long[] vals) { + for (long o : (long[]) vals) { + DataIO.packRecid(out, o); + } + } + + @Override + public long[] valueArrayDeserialize(DataInput2 in, int size) { + long[] ret = new long[size]; + for (int i = 0; i < size; i++) { + ret[i] = DataIO.unpackRecid(in); + } + return ret; + } + + @Override + public Long valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { + input.unpackLongSkip(pos); + return deserialize(input,-1); + } +} diff --git a/src/main/java/org/mapdb/ser/Serializer.java b/src/main/java/org/mapdb/ser/Serializer.java new file mode 100644 index 000000000..a6b8a6829 --- /dev/null +++ b/src/main/java/org/mapdb/ser/Serializer.java @@ -0,0 +1,66 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataInput2ByteArray; +import org.mapdb.io.DataOutput2; +import org.mapdb.io.DataOutput2ByteArray; + +import java.io.IOError; +import java.io.IOException; +import java.util.Comparator; + +/** Turns object instance into binary form and vice versa */ +public interface Serializer extends Comparator { //TODO deatach comparator from serializer??? + + void serialize(@NotNull DataOutput2 out, @NotNull K k); + + K deserialize(@NotNull DataInput2 input); + + @Nullable Class serializedType(); + + default boolean equals(@Nullable K k1, @Nullable K k2){ + return k1==k2 || (k1!=null && k1.equals(k2)); + } + + + default int hashCode(@NotNull K k){ + return k.hashCode(); //TODO better hash + } + + + default int hashCode(@NotNull K k, int hashSeed){ + return hashSeed + k.hashCode(); //TODO better mixing + } + + default K deserialize(DataInput2 in, int i){ + if(i!=-1) + throw new AssertionError(); //FIXME temp method for compatibility + + return deserialize(in); + } + + @Deprecated + default boolean isTrusted(){ + return true; + } + + default int compare(K k1, K k2){ + return ((Comparable)k1).compareTo(k2); //TODO comparators + } + + default int fixedSize() { + return -1; + } + + /** Creates binary copy of given object. If the datatype is immutable the same instance might be returned */ + default K clone(K value){ + DataOutput2 out = new DataOutput2ByteArray(); + serialize(out, value); + DataInput2 in2 = new DataInput2ByteArray(out.copyBytes()); + return deserialize(in2); + } + +} + diff --git a/src/main/java/org/mapdb/ser/SerializerIllegalAccess.java b/src/main/java/org/mapdb/ser/SerializerIllegalAccess.java new file mode 100644 index 000000000..7d9a61c9f --- /dev/null +++ b/src/main/java/org/mapdb/ser/SerializerIllegalAccess.java @@ -0,0 +1,34 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; + +/** + * Created by jan on 2/28/16. + */ +public class SerializerIllegalAccess extends DefaultGroupSerializer { + @Override + public void serialize(DataOutput2 out, E value) { + throw new IllegalAccessError(); + } + + @Override + public E deserialize(DataInput2 in) { + throw new IllegalAccessError(); + } + + @Nullable + @Override + public Class serializedType() { + return Object.class; + } + + @Override + public boolean isTrusted() { + return true; + } + +} diff --git a/src/main/java/org/mapdb/ser/SerializerUtils.java b/src/main/java/org/mapdb/ser/SerializerUtils.java new file mode 100644 index 000000000..2a995f89c --- /dev/null +++ b/src/main/java/org/mapdb/ser/SerializerUtils.java @@ -0,0 +1,63 @@ +package org.mapdb.ser; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import static org.mapdb.ser.Serializers.*; +/** + * Created by jan on 2/28/16. + */ +public final class SerializerUtils { + + + private static Map SERIALIZER_FOR_CLASS = new HashMap(); + + static { + SERIALIZER_FOR_CLASS.put(char.class, CHAR); + SERIALIZER_FOR_CLASS.put(Character.class, CHAR); + SERIALIZER_FOR_CLASS.put(String.class, STRING); + SERIALIZER_FOR_CLASS.put(long.class, LONG); + SERIALIZER_FOR_CLASS.put(Long.class, LONG); + SERIALIZER_FOR_CLASS.put(int.class, INTEGER); + SERIALIZER_FOR_CLASS.put(Integer.class, INTEGER); + SERIALIZER_FOR_CLASS.put(boolean.class, BOOLEAN); + SERIALIZER_FOR_CLASS.put(Boolean.class, BOOLEAN); + SERIALIZER_FOR_CLASS.put(byte[].class, BYTE_ARRAY); + SERIALIZER_FOR_CLASS.put(char[].class, CHAR_ARRAY); + SERIALIZER_FOR_CLASS.put(int[].class, INT_ARRAY); + SERIALIZER_FOR_CLASS.put(long[].class, LONG_ARRAY); + SERIALIZER_FOR_CLASS.put(double[].class, DOUBLE_ARRAY); + SERIALIZER_FOR_CLASS.put(UUID.class, UUID); + SERIALIZER_FOR_CLASS.put(byte.class, BYTE); + SERIALIZER_FOR_CLASS.put(Byte.class, BYTE); + SERIALIZER_FOR_CLASS.put(float.class, FLOAT); + SERIALIZER_FOR_CLASS.put(Float.class, FLOAT); + SERIALIZER_FOR_CLASS.put(double.class, DOUBLE); + SERIALIZER_FOR_CLASS.put(Double.class, DOUBLE); + SERIALIZER_FOR_CLASS.put(short.class, SHORT); + SERIALIZER_FOR_CLASS.put(Short.class, SHORT); + SERIALIZER_FOR_CLASS.put(short[].class, SHORT_ARRAY); + SERIALIZER_FOR_CLASS.put(float[].class, FLOAT_ARRAY); + SERIALIZER_FOR_CLASS.put(BigDecimal.class, BIG_DECIMAL); + SERIALIZER_FOR_CLASS.put(BigInteger.class, BIG_INTEGER); + SERIALIZER_FOR_CLASS.put(Class.class, CLASS); + SERIALIZER_FOR_CLASS.put(Date.class, DATE); + + } + + + public static Serializer serializerForClass(Class clazz){ + return SERIALIZER_FOR_CLASS.get(clazz); + } + + public static int compareInt(int x, int y) { + return (x < y) ? -1 : ((x == y) ? 0 : 1); + } + + + +} diff --git a/src/main/java/org/mapdb/ser/Serializers.java b/src/main/java/org/mapdb/ser/Serializers.java new file mode 100644 index 000000000..855223458 --- /dev/null +++ b/src/main/java/org/mapdb/ser/Serializers.java @@ -0,0 +1,109 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.DBException; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataInput2ByteArray; +import org.mapdb.io.DataOutput2; +import org.mapdb.io.DataOutput2ByteArray; + +import java.io.*; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.*; + +public final class Serializers { + + private Serializers(){} + + + /** Serializer for [java.lang.Integer] */ + public static final Serializer INTEGER = new IntegerSerializer(); + + /** Serializer for [java.lang.Long] */ + public static final Serializer LONG = new LongSerializer(); + + + /** Serializer for recids (packed 6 bytes, extra parity bit) */ + public static final Serializer RECID = new RecidSerializer(); + + /** Serializer for [java.lang.String] */ + public static final Serializer STRING = new StringSerializer(); + + public static final Serializer STRING_DELTA = new StringDeltaSerializer(); + + public static final Serializer STRING_DELTA2 = new StringDelta2Serializer(); + + + public static final Serializer STRING_NOSIZE = new StringNoSizeSerializer(); + + + /** + * Serializer for `byte[]`, but does not add extra bytes for array size. + * + * Uses [org.mapdb.io.DataInput2.available] to determine array size on deserialization. + */ + public static final Serializer BYTE_ARRAY_NOSIZE = new ByteArrayNoSizeSerializer(); + + + + public static final Serializer JAVA = new JavaSerializer(); + + public static final Serializer BYTE = new ByteSerializer(); + + /** Serializer for `byte[]`, adds extra few bytes for array size */ + public static final Serializer BYTE_ARRAY = new ByteArraySerializer(); + public static final Serializer BYTE_ARRAY_DELTA = new ByteArrayDeltaSerializer(); + public static final Serializer BYTE_ARRAY_DELTA2 = new ByteArrayDelta2Serializer(); + + + public static final Serializer CHAR = new CharSerializer(); + public static final Serializer CHAR_ARRAY = new CharArraySerializer(); + + public static final Serializer SHORT = new ShortSerializer(); + public static final Serializer SHORT_ARRAY = new ShortArraySerializer(); + + public static final Serializer FLOAT = new FloatSerializer(); + public static final Serializer FLOAT_ARRAY = new FloatArraySerializer(); + + public static final Serializer DOUBLE = new DoubleSerializer(); + public static final Serializer DOUBLE_ARRAY = new DoubleArraySerializer(); + + public static final Serializer BOOLEAN = new BooleanSerializer(); + + public static final Serializer INT_ARRAY = new IntArraySerializer(); + public static final Serializer LONG_ARRAY = new LongArraySerializer(); + + + public static final Serializer BIG_DECIMAL = new BigDecimalSerializer(); + public static final Serializer BIG_INTEGER = new BigIntegerSerializer(); + + public static final Serializer CLASS = new ClassSerializer(); + public static final Serializer DATE = new DateSerializer(); + public static final Serializer UUID = new UUIDSerializer(); + + + public static byte[] serializeToByteArray(R record, Serializer serializer) { + DataOutput2ByteArray out = new DataOutput2ByteArray(); + serializer.serialize(out,record); + return out.copyBytes(); + } + + @Nullable + public static R clone(@NotNull R r, @NotNull Serializer ser) { + byte[] b = serializeToByteArray(r, ser); + return ser.deserialize(new DataInput2ByteArray(b)); + } + + @NotNull + public static boolean binaryEqual(@NotNull Serializer ser, Object a, Object b) { + if(a==b) + return true; + if(a==null || b==null) + return false; + byte[] ba = serializeToByteArray(a, ser); + byte[] bb = serializeToByteArray(b, ser); + return Arrays.equals(ba,bb); + } +} diff --git a/src/main/java/org/mapdb/ser/ShortArraySerializer.java b/src/main/java/org/mapdb/ser/ShortArraySerializer.java new file mode 100644 index 000000000..1eb87c3d5 --- /dev/null +++ b/src/main/java/org/mapdb/ser/ShortArraySerializer.java @@ -0,0 +1,84 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; + +/** + * Created by jan on 2/28/16. + */ +public class ShortArraySerializer extends DefaultGroupSerializer { + @Override + public void serialize(DataOutput2 out, short[] value) { + out.packInt(value.length); + for (short v : value) { + out.writeShort(v); + } + } + + @Override + public short[] deserialize(DataInput2 in) { + short[] ret = new short[in.unpackInt()]; + for (int i = 0; i < ret.length; i++) { + ret[i] = in.readShort(); + } + return ret; + } + + @Nullable + @Override + public Class serializedType() { + return short[].class; + } + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public boolean equals(short[] a1, short[] a2) { + return Arrays.equals(a1, a2); + } + + @Override + public int hashCode(short[] shorts, int seed) { + for (short element : shorts) + seed = (-1640531527) * seed + element; + return seed; + } + + @Override + public int compare(short[] o1, short[] o2) { + if (o1 == o2) return 0; + final int len = Math.min(o1.length, o2.length); + for (int i = 0; i < len; i++) { + if (o1[i] == o2[i]) + continue; + if (o1[i] > o2[i]) + return 1; + return -1; + } + return SerializerUtils.compareInt(o1.length, o2.length); + } + + @Override + public short[] nextValue(short[] value) { + value = value.clone(); + + for (int i = value.length-1; ;i--) { + short b1 = value[i]; + if(b1==Short.MAX_VALUE){ + if(i==0) + return null; + value[i]=Short.MIN_VALUE; + continue; + } + value[i] = (short) (b1+1); + return value; + } + } +} diff --git a/src/main/java/org/mapdb/ser/ShortSerializer.java b/src/main/java/org/mapdb/ser/ShortSerializer.java new file mode 100644 index 000000000..78c4f5b5e --- /dev/null +++ b/src/main/java/org/mapdb/ser/ShortSerializer.java @@ -0,0 +1,41 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; + +/** + * Created by jan on 2/28/16. + */ +public class ShortSerializer extends DefaultGroupSerializer { + @Override + public void serialize(DataOutput2 out, Short value) { + out.writeShort(value.shortValue()); + } + + @Override + public Short deserialize(DataInput2 in) { + return in.readShort(); + } + + @Nullable + @Override + public Class serializedType() { + return Short.class; + } + + //TODO value array operations + + @Override + public int fixedSize() { + return 2; + } + + @Override + public boolean isTrusted() { + return true; + } + +} diff --git a/src/main/java/org/mapdb/ser/StringAsciiSerializer.java b/src/main/java/org/mapdb/ser/StringAsciiSerializer.java new file mode 100644 index 000000000..dcfe3b127 --- /dev/null +++ b/src/main/java/org/mapdb/ser/StringAsciiSerializer.java @@ -0,0 +1,57 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; + +/** + * Created by jan on 2/28/16. + */ +public class StringAsciiSerializer extends DefaultGroupSerializer { + @Override + public void serialize(DataOutput2 out, String value) { + int size = value.length(); + out.packInt(size); + for (int i = 0; i < size; i++) { + out.write(value.charAt(i)); + } + } + + @Override + public String deserialize(DataInput2 in) { + int size = in.unpackInt(); + StringBuilder result = new StringBuilder(size); + for (int i = 0; i < size; i++) { + result.append((char) in.readUnsignedByte()); + } + return result.toString(); + } + + @Nullable + @Override + public Class serializedType() { + return String.class; + } + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public int hashCode(@NotNull String s, int seed) { + return Serializers.STRING.hashCode(s, seed); + } + + // @Override +// public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) { +// if(comparator!=null && comparator!=Fun.COMPARATOR) { +// return super.getBTreeKeySerializer(comparator); +// } +// return BTreeKeySerializer.STRING; //PERF ascii specific serializer? +// } + +} diff --git a/src/main/java/org/mapdb/ser/StringDelta2Serializer.java b/src/main/java/org/mapdb/ser/StringDelta2Serializer.java new file mode 100644 index 000000000..5b12d0a40 --- /dev/null +++ b/src/main/java/org/mapdb/ser/StringDelta2Serializer.java @@ -0,0 +1,693 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.CC; +import org.mapdb.DBException; +import org.mapdb.io.DataIO; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; +import org.mapdb.ser.StringDelta2Serializer.*; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by jan on 2/29/16. + */ +public class StringDelta2Serializer implements GroupSerializer { + + public interface StringArrayKeys { + + int commonPrefixLen(); + + int length(); + + int[] getOffset(); + + StringArrayKeys deleteKey(int pos); + + StringArrayKeys copyOfRange(int from, int to); + + StringArrayKeys putKey(int pos, String newKey); + + int compare(int pos1, String string); + + int compare(int pos1, int pos2); + + String getKeyString(int pos); + + boolean hasUnicodeChars(); + + void serialize(DataOutput2 out, int prefixLen); + } + + //PERF right now byte[] contains 7 bit characters, but it should be expandable to 8bit. + public static final class ByteArrayKeys implements StringArrayKeys { + final int[] offset; + final byte[] array; + + ByteArrayKeys(int[] offset, byte[] array) { + this.offset = offset; + this.array = array; + + if(CC.ASSERT && ! (array.length==0 || array.length == offset[offset.length-1])) + throw new DBException.DataCorruption("inconsistent array size"); + } + + ByteArrayKeys(DataInput2 in, int[] offsets, int prefixLen) { + this.offset = offsets; + array = new byte[offsets[offsets.length-1]]; + + in.readFully(array, 0, prefixLen); + for(int i=0; i127) + return true; + } + return false; + } + + public ByteArrayKeys putKey(int pos, byte[] newKey) { + byte[] bb = new byte[array.length+ newKey.length]; + int split1 = pos==0? 0: offset[pos-1]; + System.arraycopy(array,0,bb,0,split1); + //$DELAY$ + System.arraycopy(newKey,0,bb,split1,newKey.length); + System.arraycopy(array,split1,bb,split1+newKey.length,array.length-split1); + + int[] offsets = new int[offset.length+1]; + + int plus = 0; + int plusI = 0; + for(int i=0;i127) + return true; + } + return false; + } + + @Override + public void serialize(DataOutput2 out, int prefixLen) { + //write rest of the suffix + outWrite(out, 0, prefixLen); + //$DELAY$ + //write suffixes + int aa = prefixLen; + for(int o:offset){ + outWrite(out, aa, o); + aa = o+prefixLen; + } + } + + private void outWrite(DataOutput2 out, int from, int to) { + for(int i=from;i>>=1; + //$DELAY$ + return useUnicode? + new CharArrayKeys(in2,offsets,prefixLen): + new ByteArrayKeys(in2,offsets,prefixLen); + + } + + @Override + public void valueArraySerialize(DataOutput2 out, StringArrayKeys vals) { + StringArrayKeys keys = (StringArrayKeys) vals; + int offset = 0; + //write sizes + for(int o: keys.getOffset()){ + out.packInt(o-offset); + offset = o; + } + //$DELAY$ + int unicode = keys.hasUnicodeChars()?1:0; + + //find and write common prefix + int prefixLen = keys.commonPrefixLen(); + out.packInt((prefixLen<<1) | unicode); + keys.serialize(out, prefixLen); + } + + @Override + public StringArrayKeys valueArrayCopyOfRange(StringArrayKeys vals, int from, int to) { + return ((StringArrayKeys)vals).copyOfRange(from,to); + } + + @Override + public StringArrayKeys valueArrayDeleteValue(StringArrayKeys vals, int pos) { + //return vals.deleteKey(pos); + Object[] vv = valueArrayToArray(vals); + vv = DataIO.arrayDelete(vv, pos, 1); + return valueArrayFromArray(vv); + } + + @Override + public StringArrayKeys valueArrayEmpty() { + return new ByteArrayKeys(new int[0], new byte[0]); + } + + @Override + public StringArrayKeys valueArrayFromArray(Object[] keys) { + if(keys.length==0) + return valueArrayEmpty(); + //$DELAY$ + boolean unicode = false; + + //fill offsets + int[] offsets = new int[keys.length]; + + int old=0; + for(int i=0;i { + @Override + public void serialize(DataOutput2 out, String value) { + out.writeUTF(value); + } + + @Override + public String deserialize(DataInput2 in) { + return in.readUTF().intern(); + } + + @Nullable + @Override + public Class serializedType() { + return String.class; + } + + @Override + public boolean isTrusted() { + return true; + } + + @Override + public int hashCode(@NotNull String s, int seed) { + return Serializers.STRING.hashCode(s, seed); + } + + +} diff --git a/src/main/java/org/mapdb/ser/StringNoSizeSerializer.java b/src/main/java/org/mapdb/ser/StringNoSizeSerializer.java new file mode 100644 index 000000000..c21b415a2 --- /dev/null +++ b/src/main/java/org/mapdb/ser/StringNoSizeSerializer.java @@ -0,0 +1,26 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; + +public class StringNoSizeSerializer implements Serializer { + + @Override + public void serialize(@NotNull DataOutput2 out, @NotNull String s) { + out.writeUTF(s); + } + + @Override + public String deserialize(@NotNull DataInput2 input) { + return input.readUTF(); + } + + @Override + public @Nullable Class serializedType() { + return String.class; + } +} diff --git a/src/main/java/org/mapdb/ser/StringOrigHashSerializer.java b/src/main/java/org/mapdb/ser/StringOrigHashSerializer.java new file mode 100644 index 000000000..ee35154fd --- /dev/null +++ b/src/main/java/org/mapdb/ser/StringOrigHashSerializer.java @@ -0,0 +1,43 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.NotNull; +import org.mapdb.io.DataIO; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; + +/** + * Created by jan on 2/28/16. + */ +public class StringOrigHashSerializer extends StringSerializer { + @Override + public void serialize(DataOutput2 out, String value) { + out.writeUTF(value); + } + + @Override + public String deserialize(DataInput2 in, int available) { + return in.readUTF(); + } + + @Override + public boolean isTrusted() { + return true; + } + + +// @Override +// public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) { +// if(comparator!=null && comparator!=Fun.COMPARATOR) { +// return super.getBTreeKeySerializer(comparator); +// } +// return BTreeKeySerializer.STRING; +// } + + + @Override + public int hashCode(@NotNull String s, int seed) { + return DataIO.intHash(s.hashCode() + seed); + } +} diff --git a/src/main/java/org/mapdb/ser/StringSerializer.java b/src/main/java/org/mapdb/ser/StringSerializer.java new file mode 100644 index 000000000..9ef1c1d70 --- /dev/null +++ b/src/main/java/org/mapdb/ser/StringSerializer.java @@ -0,0 +1,149 @@ +package org.mapdb.ser; + +import org.jetbrains.annotations.Nullable; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; + +public class StringSerializer implements GroupSerializer { + + @Override + public void serialize(DataOutput2 out, String value) { + out.writeUTF(value); + } + + @Override + public String deserialize(DataInput2 in) { + return in.readUTF(); + } + + @Nullable + @Override + public Class serializedType() { + return String.class; + } + + @Override + public boolean isTrusted() { + return true; + } + + + @Override + public void valueArraySerialize(DataOutput2 out2, char[][] vals) { + for(char[] v:(char[][])vals){ + out2.packInt(v.length); + for(char c:v){ + out2.packInt(c); + } + } + } + + @Override + public char[][] valueArrayDeserialize(DataInput2 in2, int size) { + char[][] ret = new char[size][]; + for(int i=0;i>> 1; + int compare = comparator.compare(key, new String(array[mid])); + + if (compare == 0) + return mid; + else if (compare < 0) + hi = mid - 1; + else + lo = mid + 1; + } + return -(lo + 1); + } + + @Override + public String valueArrayGet(char[][] vals, int pos) { + return new String(((char[][])vals)[pos]); + } + + @Override + public int valueArraySize(char[][] vals) { + return ((char[][])vals).length; + } + + @Override + public char[][] valueArrayEmpty() { + return new char[0][]; + } + + @Override + public char[][] valueArrayPut(char[][] vals, int pos, String newValue) { + char[][] array = (char[][]) vals; + final char[][] ret = Arrays.copyOf(array, array.length+1); + if(pos { + @Override + public void serialize(DataOutput2 out, UUID value) { + out.writeLong(value.getMostSignificantBits()); + out.writeLong(value.getLeastSignificantBits()); + } + + @Override + public UUID deserialize(DataInput2 in) { + return new UUID(in.readLong(), in.readLong()); + } + + @Nullable + @Override + public Class serializedType() { + return UUID.class; + } + + @Override + public int fixedSize() { + return 16; + } + + @Override + public boolean isTrusted() { + return true; + } + + + @Override + public int hashCode(UUID uuid, int seed) { + //on java6 uuid.hashCode is not thread safe. This is workaround + long a = uuid.getLeastSignificantBits() ^ uuid.getMostSignificantBits(); + return ((int) (a >> 32)) ^ (int) a; + + } + + + @Override + public int valueArraySearch(long[] keys, UUID key) { + return Arrays.binarySearch(valueArrayToArray(keys), key); //TODO search + } + + @Override + public int valueArraySearch(long[] keys, UUID key, Comparator comparator) { + return Arrays.binarySearch(valueArrayToArray(keys), key, comparator); //TODO search + } + + @Override + public void valueArraySerialize(DataOutput2 out, long[] vals) { + for (long o : (long[]) vals) { + out.writeLong(o); + } + } + + @Override + public long[] valueArrayDeserialize(DataInput2 in, int size) { + size *= 2; + long[] ret = new long[size]; + for (int i = 0; i < size; i++) { + ret[i] = in.readLong(); + } + return ret; + } + + @Override + public UUID valueArrayGet(long[] v, int pos) { + pos *= 2; + return new UUID(v[pos++], v[pos]); + } + + @Override + public int valueArraySize(long[] vals) { + return vals.length / 2; + } + + @Override + public long[] valueArrayEmpty() { + return new long[0]; + } + + @Override + public long[] valueArrayPut(long[] vals, int pos, UUID newValue) { + pos *= 2; + + long[] array = (long[]) vals; + final long[] ret = Arrays.copyOf(array, array.length + 2); + + if (pos < array.length) { + System.arraycopy(array, pos, ret, pos + 2, array.length - pos); + } + ret[pos++] = newValue.getMostSignificantBits(); + ret[pos] = newValue.getLeastSignificantBits(); + return ret; + } + + @Override + public long[] valueArrayUpdateVal(long[] vals, int pos, UUID newValue) { + pos *= 2; + long[] vals2 = ((long[]) vals).clone(); + vals2[pos++] = newValue.getMostSignificantBits(); + vals2[pos] = newValue.getLeastSignificantBits(); + return vals2; + } + + + @Override + public long[] valueArrayFromArray(Object[] objects) { + long[] ret = new long[objects.length * 2]; + int pos = 0; + + for (Object o : objects) { + UUID uuid = (java.util.UUID) o; + ret[pos++] = uuid.getMostSignificantBits(); + ret[pos++] = uuid.getLeastSignificantBits(); + } + + return ret; + } + + @Override + public long[] valueArrayCopyOfRange(long[] vals, int from, int to) { + return Arrays.copyOfRange((long[]) vals, from * 2, to * 2); + } + + @Override + public long[] valueArrayDeleteValue(long[] vals, int pos) { + pos *= 2; + long[] valsOrig = (long[]) vals; + long[] vals2 = new long[valsOrig.length - 2]; + System.arraycopy(vals, 0, vals2, 0, pos - 2); + System.arraycopy(vals, pos, vals2, pos - 2, vals2.length - (pos - 2)); + return vals2; + } + +} diff --git a/src/main/java/org/mapdb/store/ConcMapStore.java b/src/main/java/org/mapdb/store/ConcMapStore.java new file mode 100644 index 000000000..7c446775d --- /dev/null +++ b/src/main/java/org/mapdb/store/ConcMapStore.java @@ -0,0 +1,207 @@ +package org.mapdb.store; + +import org.jetbrains.annotations.NotNull; +import org.mapdb.DBException; +import org.mapdb.ser.Serializer; +import org.mapdb.util.MonoRef; + +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentNavigableMap; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.atomic.AtomicLong; + +public class ConcMapStore implements Store{ + + private static final Object PREALLOCATED = 1293091239012L; + + private final ConcurrentNavigableMap m; + private final ConcurrentLinkedQueue freeRecids = new ConcurrentLinkedQueue<>(); + + private final AtomicLong maxRecid = new AtomicLong(0); + + public ConcMapStore() { + this.m = new ConcurrentSkipListMap<>(); + } + + private long allocateRecid(){ + Long recid = freeRecids.poll(); + if(recid!=null) + return recid; + return maxRecid.incrementAndGet(); + } + + @Override + public long preallocate() { + long recid = allocateRecid(); + Object o = m.put(recid, PREALLOCATED); + assert(o==null); + return recid; + } + + @Override + public void preallocatePut(long recid, @NotNull Serializer serializer, @NotNull R record) { + boolean updated = m.replace(recid, PREALLOCATED, record); + if(!updated) + throw new DBException.RecordNotPreallocated(); + } + + @Override + public @NotNull long put(@NotNull R record, @NotNull Serializer serializer) { + long recid = allocateRecid(); + Object old = m.putIfAbsent(recid, record); + assert(old==null); + return recid; + } + + @Override + public void update(long recid, @NotNull Serializer serializer, @NotNull R updatedRecord) { + Object old = m.computeIfPresent(recid, (recid2, oldVal) ->{ + if(oldVal == PREALLOCATED) + throw new DBException.PreallocRecordAccess(); + return updatedRecord; + }); + if(old==null) + throw new DBException.RecordNotFound(); + } + + @Override + public @NotNull R getAndUpdate(long recid, @NotNull Serializer serializer, @NotNull R updatedRecord) { + Object old = m.computeIfPresent(recid, (recid2, oldVal) ->{ + if(oldVal == PREALLOCATED) + throw new DBException.PreallocRecordAccess(); + return updatedRecord; + }); + if(old==null) + throw new DBException.RecordNotFound(); + return (R) old; + } + + @Override + public void verify() { + + } + + @Override + public void commit() { + + } + + @Override + public void compact() { + + } + + @Override + public boolean isThreadSafe() { + return true; + } + + @Override + public @NotNull R updateAndGet(long recid, @NotNull Serializer serializer, @NotNull Transform t) { + Object newVal = m.computeIfPresent(recid, (recid2, oldVal) ->{ + if(oldVal == PREALLOCATED) + throw new DBException.PreallocRecordAccess(); + + return t.transform((R) oldVal); + }); + if(newVal == null) + throw new DBException.RecordNotFound(); + return (R) newVal; + } + + @Override + public void updateAtomic(long recid, @NotNull Serializer serializer, @NotNull Transform r) { + updateAndGet(recid, serializer, r); + } + + @Override + public boolean compareAndUpdate(long recid, @NotNull Serializer serializer, @NotNull R expectedOldRecord, @NotNull R updatedRecord) { + Object ret = m.computeIfPresent(recid, (recid2, oldVal) -> { + if (oldVal == PREALLOCATED) + throw new DBException.PreallocRecordAccess(); + return serializer.equals(expectedOldRecord, (R) oldVal) ? updatedRecord : oldVal; + }); + if(ret == null) + throw new DBException.RecordNotFound(); + return ret == updatedRecord; + } + + @Override + public boolean compareAndDelete(long recid, @NotNull Serializer serializer, @NotNull R expectedOldRecord) { + MonoRef deleted = new MonoRef(false); + Object ret = m.computeIfPresent(recid, (recid2, oldVal) -> { + if (oldVal == PREALLOCATED) + throw new DBException.PreallocRecordAccess(); + if(!serializer.equals(expectedOldRecord, (R) oldVal)){ + return oldVal; + } + deleted.ref = true; + return null; + + }); + if(ret == null && !deleted.ref) + throw new DBException.RecordNotFound(); + return deleted.ref; + } + + @Override + public void delete(long recid, @NotNull Serializer serializer) { + getAndDelete(recid, serializer); + } + + @Override + public @NotNull R getAndDelete(long recid, @NotNull Serializer serializer) { + MonoRef oldVal2 = new MonoRef(); + m.computeIfPresent(recid, (rec, oldVal) -> { + if(oldVal==PREALLOCATED) + throw new DBException.PreallocRecordAccess(); + oldVal2.ref = oldVal; + return null; + }); + if(oldVal2.ref==null) + throw new DBException.RecordNotFound(); + freeRecids.add(recid); + return (R) oldVal2.ref; + } + + @Override + public @NotNull R getAndUpdateAtomic(long recid, @NotNull Serializer serializer, @NotNull Transform t) { + MonoRef oldVal2 = new MonoRef(); + Object newVal = m.computeIfPresent(recid, (recid2, oldVal) ->{ + if(oldVal == PREALLOCATED) + throw new DBException.PreallocRecordAccess(); + oldVal2.ref = oldVal; + + return t.transform((R) oldVal); + }); + if(newVal == null) + throw new DBException.RecordNotFound(); + return (R) oldVal2.ref; + } + + @Override + public @NotNull K get(long recid, @NotNull Serializer ser) { + Object old = m.get(recid); + if(old==null) + throw new DBException.RecordNotFound(); + if(old==PREALLOCATED) + throw new DBException.PreallocRecordAccess(); + return (K) old; + } + + @Override + public void close() { + + } + + @Override + public void getAll(@NotNull GetAllCallback callback) { + throw new UnsupportedOperationException(); + } + + + @Override + public boolean isEmpty() { + return m.isEmpty(); + } +} diff --git a/src/main/java/org/mapdb/store/FileHeapBufStore.java b/src/main/java/org/mapdb/store/FileHeapBufStore.java new file mode 100644 index 000000000..c9f89e5b3 --- /dev/null +++ b/src/main/java/org/mapdb/store/FileHeapBufStore.java @@ -0,0 +1,92 @@ +package org.mapdb.store; + +import org.mapdb.util.IO; + +import java.io.*; + +public class FileHeapBufStore extends HeapBufStore{ + + protected final File file; + + //-newRWLOCK + + public FileHeapBufStore(File file) { + this.file = file; + + //-WLOCK + reload(); + //-WUNLOCK + } + + protected void reload() { + //-AWLOCKED + clear(); + + try(DataInputStream is = new DataInputStream(new FileInputStream(file))) { + long maxRecid = 0; + + //load records + long recCount = IO.readLong(is); + for(long i=0;i{ + try { + IO.writeLong(out, recid); + int size = buf==PREALLOC_RECORD? -1 : buf.length; + IO.writeInt(out, size); + if(size>0) + IO.writeByteArray(out, buf); + }catch(IOException e){ + throw new IOError(e); + } + }); + + out.flush(); + } catch (FileNotFoundException e) { + throw new IOError(e); //file could not be created + } catch (IOException e) { + throw new IOError(e); + } + } + public void close() { + //-WLOCK + save(); + //-WUNLOCK + } + + private void clear() { + //-AWLOCK + freeRecids.clear(); + freeRecids.trimToSize(); + records.clear(); + records.compact(); + } +} diff --git a/src/main/java/org/mapdb/store/HeapBufStore.java b/src/main/java/org/mapdb/store/HeapBufStore.java new file mode 100644 index 000000000..ae058196e --- /dev/null +++ b/src/main/java/org/mapdb/store/HeapBufStore.java @@ -0,0 +1,228 @@ +package org.mapdb.store; + +import org.eclipse.collections.impl.list.mutable.primitive.LongArrayList; +import org.eclipse.collections.impl.map.mutable.primitive.LongObjectHashMap; +import org.jetbrains.annotations.NotNull; +import org.mapdb.DBException; +import org.mapdb.io.DataInput2ByteArray; +import org.mapdb.ser.Serializer; +import org.mapdb.ser.Serializers; + +public class HeapBufStore implements Store { + + protected static final byte[] PREALLOC_RECORD = new byte[]{1,2,4}; + + //-newRWLOCK + + protected final LongObjectHashMap records = LongObjectHashMap.newMap(); + + protected final LongArrayList freeRecids = new LongArrayList(); + + + protected long maxRecid = 0L; + + @Override + public long preallocate() { + //-WLOCK + return preallocate2(); + //-WUNLOCK + } + + @Override + public void preallocatePut(long recid, @NotNull Serializer serializer, @NotNull R record) { + byte[] data = serialize(serializer, record); + //-WLOCK + byte[] old = records.get(recid); + if(old==null) + throw new DBException.RecordNotPreallocated(); + if(old!=PREALLOC_RECORD) + throw new DBException.RecordNotPreallocated(); + records.put(recid, data); + //-WUNLOCK + } + + protected long preallocate2(){ + //-AWLOCKED + long recid = + freeRecids.isEmpty()? + ++maxRecid : + freeRecids.removeAtIndex(freeRecids.size()-1); + records.put(recid, PREALLOC_RECORD); + return recid; + } + + @Override + public long put(K record, Serializer serializer) { + byte[] data = serialize(serializer, record); + //-WLOCK + long recid = preallocate2(); + records.put(recid, data); + return recid; + //-WUNLOCK + } + + protected byte[] serialize(Serializer serializer, K record) { + if(record == null) + throw new NullPointerException(); + return Serializers.serializeToByteArray(record, serializer); + } + + protected E deser(Serializer ser, byte[] value){ + if(value == PREALLOC_RECORD) + throw new DBException.PreallocRecordAccess(); + if(value == null) + throw new DBException.RecordNotFound(); + return ser.deserialize(new DataInput2ByteArray(value)); + } + + + private byte[] checkExists(long recid) { + byte[] old = records.get(recid); + if(old == PREALLOC_RECORD) + throw new DBException.PreallocRecordAccess(); + if(old == null) + throw new DBException.RecordNotFound(); + + return old; + } + + + @Override + public void update(long recid, Serializer serializer, K updatedRecord) { + byte[] newData = serialize(serializer, updatedRecord); + //-WLOCK + checkExists(recid); + records.put(recid, newData); + //-WUNLOCK + } + + + @Override + public void updateAtomic(long recid, Serializer serializer, Transform r) { + //-WLOCK + checkExists(recid); + + R oldRec = deser(serializer, records.get(recid)); + R newRec = r.transform(oldRec); + byte[] newVal = serialize(serializer, newRec); + + records.put(recid, newVal); + //-WUNLOCK + } + + + @Override + public boolean compareAndUpdate(long recid, Serializer serializer, R expectedOldRecord, R updatedRecord) { + //-WLOCK + byte[] b = checkExists(recid); + R rec = deser(serializer, b); + if(!serializer.equals(rec, expectedOldRecord)) + return false; + b = serialize(serializer, updatedRecord); + records.put(recid, b); + return true; + //-WUNLOCK + } + + @Override + public boolean compareAndDelete(long recid, Serializer serializer, R expectedOldRecord) { + //-WLOCK + byte[] b = checkExists(recid); + R rec = deser(serializer, b); + if(!serializer.equals(rec, expectedOldRecord)) + return false; + delete2(recid); + return true; + //-WUNLOCK + } + + @Override + public void delete(long recid, Serializer serializer) { + //-WLOCK + delete2(recid); + //-WUNLOCK + } + + protected void delete2(long recid) { + //-ARLOCKED + byte[] buf = records.removeKey(recid); + if(buf == null) + throw new DBException.RecordNotFound(); + if(buf == PREALLOC_RECORD) { + records.put(recid, PREALLOC_RECORD); + throw new DBException.PreallocRecordAccess(); + } + + freeRecids.add(recid); + } + + @Override + public R getAndDelete(long recid, Serializer serializer) { + byte[] buf = null; + //-WLOCK + buf = checkExists(recid); + delete2(recid); + //-WUNLOCK + return deser(serializer, buf); + } + + @Override + public K get(long recid, Serializer ser) { + if(recid<=0) + throw new DBException.RecordNotFound(); + byte[] buf = null; + //--RLOCK + buf = checkExists(recid); + //-RUNLOCK + + return deser(ser, buf); + } + + + @Override + public void getAll(GetAllCallback callback) { + //--RLOCK + records.forEachKeyValue( + (recid, buf) -> { + if (buf != PREALLOC_RECORD) + callback.takeOne(recid, buf); + }); + //-RUNLOCK + } + + + @Override + public boolean isEmpty() { + //-RLOCK + return records.isEmpty(); + //-RUNLOCK + } + + @Override + public void close() { + } + + + @Override + public void verify() { + } + + @Override + public void commit() { + + } + + @Override + public void compact() { + //-WLOCK + records.compact(); + freeRecids.trimToSize(); + //-WUNLOCK + } + + @Override + public boolean isThreadSafe() { + return false; + } + +} diff --git a/src/main/java/org/mapdb/store/ReadonlyStore.java b/src/main/java/org/mapdb/store/ReadonlyStore.java new file mode 100644 index 000000000..35779a5e2 --- /dev/null +++ b/src/main/java/org/mapdb/store/ReadonlyStore.java @@ -0,0 +1,37 @@ +package org.mapdb.store; + +import org.jetbrains.annotations.NotNull; +import org.mapdb.ser.Serializer; + +import java.io.Closeable; + +public interface ReadonlyStore extends Closeable { + + + /** + * Get existing record + * + * @return record or null if record was not allocated yet, or was deleted + **/ + @NotNull K get(long recid, @NotNull Serializer ser); + + void close(); + + /** + * Iterates over all records in store. + * + * Function takes recid and binary data + */ + void getAll(@NotNull GetAllCallback callback); + + interface GetAllCallback{ + void takeOne(long recid, @NotNull byte[] data); + } + + /** + * Returns true if store does not contain any data and no recids were allocated yet. + * Store is usually empty just after creation. + */ + boolean isEmpty(); + +} diff --git a/src/main/java/org/mapdb/store/Recids.java b/src/main/java/org/mapdb/store/Recids.java new file mode 100644 index 000000000..bd90248e6 --- /dev/null +++ b/src/main/java/org/mapdb/store/Recids.java @@ -0,0 +1,9 @@ +package org.mapdb.store; + +public class Recids { + + public static final long RECID_NAME_PARAMS = 1L; + + public static final long RECID_MAX_RESERVED = 255L; + +} diff --git a/src/main/java/org/mapdb/store/Store.java b/src/main/java/org/mapdb/store/Store.java new file mode 100644 index 000000000..d13c7c1d4 --- /dev/null +++ b/src/main/java/org/mapdb/store/Store.java @@ -0,0 +1,82 @@ +package org.mapdb.store; + +import org.jetbrains.annotations.NotNull; +import org.mapdb.ser.Serializer; + +public interface Store extends ReadonlyStore{ + + + /** allocates new null record, and returns its recid. It can be latter updated with `updateAtomic()` or `cas` */ + long preallocate(); + + void preallocatePut(long recid, @NotNull Serializer serializer, @NotNull R record); + + default void preallocate(long[] recids) { + for(int i=0;i long put(@NotNull R record, @NotNull Serializer serializer); + + /** updateAtomic existing record with new value */ + void update(long recid, @NotNull Serializer serializer, @NotNull R updatedRecord); + + + @NotNull default R getAndUpdate(long recid, @NotNull Serializer serializer, @NotNull R updatedRecord) { + R old = get(recid,serializer); + update(recid, serializer, updatedRecord); + return old; //TODO atomic + + } + + void verify(); + + void commit(); + + void compact(); + + boolean isThreadSafe(); + + + + + interface Transform{ + @NotNull R transform(@NotNull R r); + } + + @NotNull default R updateAndGet(long recid, @NotNull Serializer serializer, @NotNull Transform t) { + R old = get(recid,serializer); + R newRec = t.transform(old); + update(recid, serializer, newRec); + return newRec; //TODO atomic + } + + @NotNull default R getAndUpdateAtomic(long recid, @NotNull Serializer serializer, @NotNull Transform t) { + R old = get(recid,serializer); + R newRec = t.transform(old); + update(recid, serializer, newRec); + return old; //TODO atomic + } + + + void updateAtomic(long recid, @NotNull Serializer serializer, @NotNull Transform r); + + /** atomically compares and swap records + * @return true if compare was sucessfull and record was swapped, else false + */ + boolean compareAndUpdate(long recid, @NotNull Serializer serializer, @NotNull R expectedOldRecord, @NotNull R updatedRecord); + + boolean compareAndDelete(long recid, @NotNull Serializer serializer, @NotNull R expectedOldRecord); + + /** delete existing record */ + void delete(long recid, @NotNull Serializer serializer); + + @NotNull R getAndDelete(long recid, @NotNull Serializer serializer); + + default int maxRecordSize() { + return Integer.MAX_VALUE; + } + +} diff --git a/src/main/java/org/mapdb/store/StoreTx.java b/src/main/java/org/mapdb/store/StoreTx.java new file mode 100644 index 000000000..814ee5de4 --- /dev/null +++ b/src/main/java/org/mapdb/store/StoreTx.java @@ -0,0 +1,7 @@ +package org.mapdb.store; + +public interface StoreTx extends Store { + void commit(); + void rollback(); + +} diff --git a/src/main/java/org/mapdb/store/legacy/DataInput2Exposed.java b/src/main/java/org/mapdb/store/legacy/DataInput2Exposed.java new file mode 100644 index 000000000..41d1a85cd --- /dev/null +++ b/src/main/java/org/mapdb/store/legacy/DataInput2Exposed.java @@ -0,0 +1,119 @@ +package org.mapdb.store.legacy; + +import org.mapdb.io.DataInput2; + +import java.nio.ByteBuffer; + +/** DataInput on top of {@code byte[]} */ +public final class DataInput2Exposed implements DataInput2 { + + protected final ByteBuffer buf; + protected int pos; + + public DataInput2Exposed(ByteBuffer b) { + this(b, 0); + } + + public DataInput2Exposed(ByteBuffer bb, int pos) { + buf = bb; + this.pos = pos; + } + + public int getPos(){ + return pos; + } + + @Override + public void readFully(byte[] b, int off, int len) { + ByteBuffer clone = buf.duplicate(); + clone.position(pos); + pos+=len; + clone.get(b,off,len); + } + + @Override + public int skipBytes(final int n) { + pos += n; + return n; + } + + @Override + public boolean readBoolean() { + return buf.get(pos++) ==1; + } + + @Override + public byte readByte() { + return buf.get(pos++); + } + + @Override + public int readUnsignedByte() { + return buf.get(pos++)& 0xff; + } + + @Override + public short readShort() { + final short ret = buf.getShort(pos); + pos+=2; + return ret; + } + + @Override + public char readChar() { + final char ret = buf.getChar(pos); + pos+=2; + return ret; + } + + @Override + public int readInt() { + final int ret = buf.getInt(pos); + pos+=4; + return ret; + } + + @Override + public long readLong() { + final long ret = buf.getLong(pos); + pos+=8; + return ret; + } + + + @Override + public int available() { + return buf.limit()-pos; + } + + @Override + public boolean availableMore() { + return available()>0; + } + + @Override + public int readPackedInt() { + return readInt(); + } + + @Override + public long readPackedLong() { + return readLong(); + } + + + @Override + public void unpackLongSkip(int count) { + int pos2 = this.pos; + while(count>0){ +// count -= (b[pos2++]&0x80)>>7; + //TODO go back to packed longs, remove code bellow + readLong(); + count--; + pos2+=8; + } + this.pos = pos2; + } + +} + diff --git a/src/main/java/org/mapdb/store/legacy/Fun.java b/src/main/java/org/mapdb/store/legacy/Fun.java new file mode 100644 index 000000000..28b83f564 --- /dev/null +++ b/src/main/java/org/mapdb/store/legacy/Fun.java @@ -0,0 +1,8 @@ +package org.mapdb.store.legacy; + +public class Fun { + public static long roundUp(long number, long roundUpToMultipleOf) { + return ((number+roundUpToMultipleOf-1)/(roundUpToMultipleOf))*roundUpToMultipleOf; + } + +} diff --git a/src/main/java/org/mapdb/LongConcurrentHashMap.java b/src/main/java/org/mapdb/store/legacy/LongConcurrentHashMap.java similarity index 96% rename from src/main/java/org/mapdb/LongConcurrentHashMap.java rename to src/main/java/org/mapdb/store/legacy/LongConcurrentHashMap.java index c893103e1..022673b49 100644 --- a/src/main/java/org/mapdb/LongConcurrentHashMap.java +++ b/src/main/java/org/mapdb/store/legacy/LongConcurrentHashMap.java @@ -22,7 +22,8 @@ * http://creativecommons.org/licenses/publicdomain */ -package org.mapdb; +package org.mapdb.store.legacy; + import java.io.Serializable; import java.util.Iterator; import java.util.NoSuchElementException; @@ -238,7 +239,7 @@ static final class Segment extends ReentrantLock implements Serializable { final float loadFactor; Segment(int initialCapacity, float lf) { - super(CC.FAIR_LOCKS); + super(); loadFactor = lf; setTable(HashEntry.newArray(initialCapacity)); } @@ -484,7 +485,7 @@ V remove(final long key, int hash, Object value) { HashEntry newFirst = e.next; for (HashEntry p = first; p != e; p = p.next) newFirst = new HashEntry(p.key, p.hash, - newFirst, p.value); + newFirst, p.value); tab[index] = newFirst; count = c; // write-volatile } @@ -590,7 +591,7 @@ public LongConcurrentHashMap() { * @return true if this map contains no key-value mappings */ @Override - public boolean isEmpty() { + public boolean isEmpty() { final Segment[] segments = this.segments; /* * We keep track of per-segment modCounts to avoid ABA @@ -615,7 +616,7 @@ public boolean isEmpty() { if (mcsum != 0) { for (int i = 0; i < segments.length; ++i) { if (segments[i].count != 0 || - mc[i] != segments[i].modCount) + mc[i] != segments[i].modCount) return false; } } @@ -630,7 +631,7 @@ public boolean isEmpty() { * @return the number of key-value mappings in this map */ @Override - public int size() { + public int size() { final Segment[] segments = this.segments; long sum = 0; long check = 0; @@ -691,8 +692,8 @@ public LongMapIterator longMapIterator() { * @throws NullPointerException if the specified key is null */ @Override - public V get(long key) { - final int hash = DataIO.longHash(key ^ hashSalt); + public V get(long key) { + final int hash = LongHashMap.longHash(key^hashSalt); return segmentFor(hash).get(key, hash); } @@ -706,7 +707,7 @@ public V get(long key) { * @throws NullPointerException if the specified key is null */ public boolean containsKey(long key) { - final int hash = DataIO.longHash(key ^ hashSalt); + final int hash = LongHashMap.longHash(key^hashSalt); return segmentFor(hash).containsKey(key, hash); } @@ -784,15 +785,15 @@ public boolean containsValue(Object value) { * @throws NullPointerException if the specified key or value is null */ @Override - public V put(long key, V value) { + public V put(long key, V value) { if (value == null) throw new NullPointerException(); - final int hash = DataIO.longHash(key ^ hashSalt); + final int hash = LongHashMap.longHash(key^hashSalt); return segmentFor(hash).put(key, hash, value, false); } /** - * + * * * @return the previous value associated with the specified key, * or null if there was no mapping for the key @@ -801,7 +802,7 @@ public V put(long key, V value) { public V putIfAbsent(long key, V value) { if (value == null) throw new NullPointerException(); - final int hash = DataIO.longHash(key ^ hashSalt); + final int hash = LongHashMap.longHash(key^hashSalt); return segmentFor(hash).put(key, hash, value, true); } @@ -816,35 +817,35 @@ public V putIfAbsent(long key, V value) { * @throws NullPointerException if the specified key is null */ @Override - public V remove(long key) { - final int hash = DataIO.longHash(key ^ hashSalt); + public V remove(long key) { + final int hash = LongHashMap.longHash(key^hashSalt); return segmentFor(hash).remove(key, hash, null); } /** - * + * * * @throws NullPointerException if the specified key is null */ public boolean remove(long key, Object value) { - final int hash = DataIO.longHash(key ^ hashSalt); + final int hash = LongHashMap.longHash(key^hashSalt); return value != null && segmentFor(hash).remove(key, hash, value) != null; } /** - * + * * * @throws NullPointerException if any of the arguments are null */ public boolean replace(long key, V oldValue, V newValue) { if (oldValue == null || newValue == null) throw new NullPointerException(); - final int hash = DataIO.longHash(key ^ hashSalt); + final int hash = LongHashMap.longHash(key^hashSalt); return segmentFor(hash).replace(key, hash, oldValue, newValue); } /** - * + * * * @return the previous value associated with the specified key, * or null if there was no mapping for the key @@ -853,7 +854,7 @@ public boolean replace(long key, V oldValue, V newValue) { public V replace(long key, V value) { if (value == null) throw new NullPointerException(); - final int hash = DataIO.longHash(key ^ hashSalt); + final int hash = LongHashMap.longHash(key^hashSalt); return segmentFor(hash).replace(key, hash, value); } @@ -861,7 +862,7 @@ public V replace(long key, V value) { * Removes all of the mappings from this map. */ @Override - public void clear() { + public void clear() { for (Segment segment : segments) segment.clear(); } @@ -927,19 +928,19 @@ public void remove() { } final class KeyIterator - extends HashIterator - implements Iterator + extends HashIterator + implements Iterator { @Override - public Long next() { return super.nextEntry().key; } + public Long next() { return super.nextEntry().key; } } final class ValueIterator - extends HashIterator - implements Iterator + extends HashIterator + implements Iterator { @Override - public V next() { return super.nextEntry().value; } + public V next() { return super.nextEntry().value; } } diff --git a/src/main/java/org/mapdb/LongHashMap.java b/src/main/java/org/mapdb/store/legacy/LongHashMap.java similarity index 94% rename from src/main/java/org/mapdb/LongHashMap.java rename to src/main/java/org/mapdb/store/legacy/LongHashMap.java index f58884dc2..10a06348e 100644 --- a/src/main/java/org/mapdb/LongHashMap.java +++ b/src/main/java/org/mapdb/store/legacy/LongHashMap.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.mapdb; +package org.mapdb.store.legacy; import java.io.Serializable; import java.util.*; @@ -192,7 +192,7 @@ private static class ValueIterator extends AbstractMapIterator implements } @Override - public V next() { + public V next() { makeNext(); return currentEntry.value; } @@ -316,7 +316,7 @@ public V get(long key) { } final Entry getEntry(long key) { - int hash = DataIO.longHash(key ^ hashSalt); + int hash = LongHashMap.longHash(key^hashSalt); int index = hash & (elementData.length - 1); return findNonNullKeyEntry(key, index, hash); } @@ -357,15 +357,15 @@ public boolean isEmpty() { @Override public V put(long key, V value) { Entry entry; - int hash = DataIO.longHash(key ^ hashSalt); + int hash = LongHashMap.longHash(key^hashSalt); int index = hash & (elementData.length - 1); entry = findNonNullKeyEntry(key, index, hash); if (entry == null) { - modCount++; - entry = createHashedEntry(key, index, hash); - if (++elementCount > threshold) { - rehash(); - } + modCount++; + entry = createHashedEntry(key, index, hash); + if (++elementCount > threshold) { + rehash(); + } } V result = entry.value; @@ -429,12 +429,12 @@ final Entry removeEntry(long key) { Entry entry; Entry last = null; - int hash = DataIO.longHash(key ^ hashSalt); + int hash = LongHashMap.longHash(key^hashSalt); index = hash & (elementData.length - 1); entry = elementData[index]; while (entry != null && !(entry.origKeyHash == hash && key == entry.key)) { - last = entry; - entry = entry.next; + last = entry; + entry = entry.next; } if (entry == null) { @@ -471,4 +471,20 @@ public LongMapIterator longMapIterator() { } + + public static int longHash(final long key) { + int h = (int)(key ^ (key >>> 32)); + h ^= (h >>> 20) ^ (h >>> 12); + return h ^ (h >>> 7) ^ (h >>> 4); + } + + + + public static int intHash(int h) { + h ^= (h >>> 20) ^ (h >>> 12); + return h ^ (h >>> 7) ^ (h >>> 4); + } + + + } diff --git a/src/main/java/org/mapdb/LongMap.java b/src/main/java/org/mapdb/store/legacy/LongMap.java similarity index 98% rename from src/main/java/org/mapdb/LongMap.java rename to src/main/java/org/mapdb/store/legacy/LongMap.java index 40709bfe3..5b94a1c7c 100644 --- a/src/main/java/org/mapdb/LongMap.java +++ b/src/main/java/org/mapdb/store/legacy/LongMap.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.mapdb; +package org.mapdb.store.legacy; import java.util.Iterator; diff --git a/src/main/java/org/mapdb/store/legacy/Store2.java b/src/main/java/org/mapdb/store/legacy/Store2.java new file mode 100644 index 000000000..8da9ee615 --- /dev/null +++ b/src/main/java/org/mapdb/store/legacy/Store2.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2012 Jan Kotek + * + * 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 + * + * http://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. + */ +package org.mapdb.store.legacy; + +import org.mapdb.CC; +import org.mapdb.io.DataOutput2ByteArray; +import org.mapdb.ser.Serializer; +import org.mapdb.ser.Serializers; +import org.mapdb.store.Store; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.logging.Logger; + +/** + * Low level record store. + */ +public abstract class Store2 implements Store { + + protected static final Logger LOG = Logger.getLogger(Store.class.getName()); + + public static final int VOLUME_CHUNK_SHIFT = 20; // 1 MB + + protected final static int CHECKSUM_FLAG_MASK = 1; + protected final static int COMPRESS_FLAG_MASK = 1<<2; + protected final static int ENCRYPT_FLAG_MASK = 1<<3; + + + protected static final int CHUNK_SIZE = 1<< VOLUME_CHUNK_SHIFT; + + + protected static final int CHUNK_SIZE_MOD_MASK = CHUNK_SIZE -1; + + public abstract long getMaxRecid(); + public abstract ByteBuffer getRaw(long recid); + public abstract Iterator getFreeRecids(); + public abstract void updateRaw(long recid, ByteBuffer data); + + /** returns maximal store size or `0` if there is no limit */ + public abstract long getSizeLimit(); + + /** returns current size occupied by physical store (does not include index). It means file allocated by physical file */ + public abstract long getCurrSize(); + + /** returns free size in physical store (does not include index). */ + public abstract long getFreeSize(); + + /** get some statistics about store. This may require traversing entire store, so it can take some time.*/ + public abstract String calculateStatistics(); + + public void printStatistics(){ + System.out.println(calculateStatistics()); + } + + protected Lock serializerPojoInitLock = new ReentrantLock(); + + + protected final ReentrantLock structuralLock = new ReentrantLock(); + protected final ReentrantReadWriteLock newRecidLock = new ReentrantReadWriteLock(); + protected final ReentrantReadWriteLock locks = new ReentrantReadWriteLock(); + + protected void lockAllWrite() { + newRecidLock.writeLock().lock(); + locks.writeLock().lock(); + structuralLock.lock(); + } + + protected void unlockAllWrite() { + structuralLock.unlock(); + locks.writeLock().unlock(); + newRecidLock.writeLock().unlock(); + } + + protected DataOutput2ByteArray serialize(A value, Serializer serializer){ + if(value==null) + return null; + + DataOutput2ByteArray out = newDataOut2(); + + serializer.serialize(out,value); + + if(out.pos>0){ + + if(CC.PARANOID)try{ + //check that array is the same after deserialization + DataInput2Exposed inp = new DataInput2Exposed(ByteBuffer.wrap(Arrays.copyOf(out.buf,out.pos))); + byte[] decompress = deserialize(Serializers.BYTE_ARRAY_NOSIZE,out.pos,inp); + + DataOutput2ByteArray expected = newDataOut2(); + serializer.serialize(expected,value); + + byte[] expected2 = Arrays.copyOf(expected.buf, expected.pos); + //check arrays equals + assert(Arrays.equals(expected2,decompress)); + + + }catch(Exception e){ + throw new RuntimeException(e); + } + } + return out; + + } + + protected DataOutput2ByteArray newDataOut2() { + return new DataOutput2ByteArray(); + } + + + protected A deserialize(Serializer serializer, int size, DataInput2Exposed di) throws IOException { + + int start = di.pos; + + A ret = serializer.deserialize(di); + if(size+start>di.pos) + throw new AssertionError("data were not fully read, check your serializer "); + if(size+start closeListeners = new CopyOnWriteArrayList(); + + public void closeListenerRegister(Runnable closeListener) { + closeListeners.add(closeListener); + } + + public void closeListenerUnregister(Runnable closeListener) { + closeListeners.remove(closeListener); + } + +} diff --git a/src/main/java/org/mapdb/StoreDirect.java b/src/main/java/org/mapdb/store/legacy/StoreDirect.java similarity index 72% rename from src/main/java/org/mapdb/StoreDirect.java rename to src/main/java/org/mapdb/store/legacy/StoreDirect.java index 0c7a609a8..fb127022e 100644 --- a/src/main/java/org/mapdb/StoreDirect.java +++ b/src/main/java/org/mapdb/store/legacy/StoreDirect.java @@ -13,17 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.mapdb; +package org.mapdb.store.legacy; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mapdb.CC; +import org.mapdb.DBException; +import org.mapdb.io.DataOutput2ByteArray; +import org.mapdb.ser.Serializer; +import org.mapdb.ser.Serializers; -import java.io.DataInput; import java.io.File; import java.io.IOError; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.concurrent.locks.Lock; -import java.util.logging.Level; /** * Storage Engine which saves record directly into file. @@ -48,23 +55,22 @@ * * Basic **structure of index file** is bellow. Each slot is 8-bytes long so `offset=slot*8` * - * - * + * slot | in code | description + * --- | --- | --- + * 0 | {@link StoreDirect#HEADER} | File header, format version and flags + * 1 | {@link StoreDirect#IO_INDEX_SIZE} | Allocated file size of index file in bytes. + * 2 | {@link StoreDirect#IO_PHYS_SIZE} | Allocated file size of physical file in bytes. + * 3 | {@link StoreDirect#IO_FREE_SIZE} | Space occupied by free records in physical file in bytes. + * 4 | {@link StoreDirect#IO_INDEX_SUM} | Checksum of all Index file headers. Checks if store was closed correctly + * 5..9 | | Reserved for future use + * 10..14 | | For usage by user + * 15 | {@link StoreDirect#IO_FREE_RECID} |Long Stack of deleted recids, those will be reused and returned by {@code Engine#put(Object, Serializer)} + * 16..4111 | |Long Stack of free physical records. This contains free space released by record update or delete. Each slots corresponds to free record size. TODO check 4111 is right + * 4112 | {@link StoreDirect#IO_USER_START} |Record size and offset in physical file for recid=1 + * 4113 | |Record size and offset in physical file for recid=2 + * ... | ... |... snip ... + * N+4111 | |Record size and offset in physical file for recid=N * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
slot in code description
0 {@link StoreDirect#HEADER} File header, format version and flags
1 {@link StoreDirect#IO_INDEX_SIZE} Allocated file size of index file in bytes.
2 {@link StoreDirect#IO_PHYS_SIZE} Allocated file size of physical file in bytes.
3 {@link StoreDirect#IO_FREE_SIZE} Space occupied by free records in physical file in bytes.
4 {@link StoreDirect#IO_INDEX_SUM} Checksum of all Index file headers. Checks if store was closed correctly
5..9 Reserved for future use
10..14 For usage by user
15 {@link StoreDirect#IO_FREE_RECID} Long Stack of deleted recids, those will be reused and returned by {@link Engine#put(Object, Serializer)}
16..4111 Long Stack of free physical records. This contains free space released by record update or delete. Each slots corresponds to free record size. TODO check 4111 is right
4112 {@link StoreDirect#IO_USER_START} Record size and offset in physical file for recid=1
4113 Record size and offset in physical file for recid=2
... ... ... snip ...
N+4111 Record size and offset in physical file for recid=N
* * Long Stack * ------------ @@ -72,15 +78,13 @@ * Long Stack is identified by slot in Index File, which stores pointer to Long Stack head. The structure of * of index pointer is following: * - *
{@code
  *  byte    | description
  *  ---     |---
  *  0..1    | relative offset in head Long Stack Record to take value from. This value decreases by 8 each take
  *  2..7    | physical file offset of head Long Stack Record, zero if Long Stack is empty
- * }
+ * * Each Long Stack Record is sequence of 8-byte longs, first slot is header. Long Stack Record structure is following: * - *
{@code
  *  byte    | description
  *  ---     |---
  *  0..1    | length of current Long Stack Record in bytes
@@ -88,7 +92,7 @@
  *  8-15    | Long Stack value
  *  16-23   | Long Stack value
  *   ...    | and so on until end of Long Stack Record
- * }
+ * * Physical pointer * ---------------- * Index slot value typically contains physical pointer (information about record location and size in physical file). First 2 bytes @@ -96,16 +100,15 @@ * Physical file offset must always be multiple of 16, so last 4 bites are used to flag extra record information. * Structure of **physical pointer**: * - *
{@code
  * bite     | in code                                   | description
  *   ---    | ---                                       | ---
  * 0-15     |`val>>>48`                                 | record size
  * 16-59    |`val&{@link StoreDirect#MASK_OFFSET}`      | physical offset
  * 60       |`val&{@link StoreDirect#MASK_LINKED}!=0`   | linked record flag
- * 61       |`val&{@link StoreDirect#MASK_DISCARD}!=0`  | to be discarded while storage is offline flag
+ * 61       |`val&{@link StoreDirect#MASK_PREALLOC}!=0`  | to be discarded while storage is offline flag
  * 62       |`val&{@link StoreDirect#MASK_ARCHIVE}!=0`  | record modified since last backup flag
  * 63       |                                           | not used yet
- * }
+ * * Records in Physical File * --------------------------- * Records are stored in physical file. Maximal record size size is 64KB, so larger records must @@ -120,12 +123,12 @@ * * @author Jan Kotek */ -public class StoreDirect extends Store{ +public class StoreDirect extends Store2 { protected static final long MASK_OFFSET = 0x0000FFFFFFFFFFF0L; protected static final long MASK_LINKED = 0x8L; - protected static final long MASK_DISCARD = 0x4L; + protected static final long MASK_PREALLOC = 0x4L; protected static final long MASK_ARCHIVE = 0x2L; /** 4 byte file header */ @@ -165,6 +168,8 @@ public class StoreDirect extends Store{ protected final static long LONG_STACK_PREF_SIZE_ALTER = 8+LONG_STACK_PREF_COUNT_ALTER*6; + protected static final long INDEX_VAL_ZERO_SIZE = MASK_ARCHIVE + 16; + protected Volume index; protected Volume phys; @@ -187,26 +192,10 @@ public class StoreDirect extends Store{ /** maximal non zero slot in free phys record, access requires `structuralLock`*/ protected long maxUsedIoList = 0; - protected Fun.Function1 indexVolumeFactory; - public StoreDirect( - String fileName, - Fun.Function1 volumeFactory, - Fun.Function1 indexVolumeFactory, - boolean readOnly, - boolean deleteFilesAfterClose, - int spaceReclaimMode, - boolean syncOnCommitDisabled, - long sizeLimit, - boolean checksum, - boolean compress, - byte[] password, - int sizeIncrement) { - super(fileName, volumeFactory, checksum, compress, password); - - this.indexVolumeFactory = indexVolumeFactory; - + public StoreDirect(Volume.Factory volFac, boolean readOnly, boolean deleteFilesAfterClose, + int spaceReclaimMode, boolean syncOnCommitDisabled, long sizeLimit) { this.readOnly = readOnly; this.deleteFilesAfterClose = deleteFilesAfterClose; this.syncOnCommitDisabled = syncOnCommitDisabled; @@ -219,8 +208,8 @@ public StoreDirect( boolean allGood = false; try{ - index = indexVolumeFactory.run(fileName); - phys = volumeFactory.run(fileName+DATA_FILE_EXT); + index = volFac.createIndexVolume(); + phys = volFac.createPhysVolume(); if(index.isEmpty()){ createStructure(); }else{ @@ -237,36 +226,41 @@ public StoreDirect( }finally{ if(!allGood){ //exception was thrown, try to unlock files - if(index!=null){ - index.sync(); - index.close(); - index = null; - } - if(phys!=null){ - phys.sync(); - phys.close(); - phys = null; + //We have to wrap everything in try finally blocks as we must try to unlock as many files + //as possible. If we fail to close index we should still try to close the phys file. + try { + if(index!=null){ + try { + index.sync(); + } finally { + index.close(); + } + index = null; + } + } finally { + if(phys!=null){ + try { + phys.sync(); + } finally { + phys.close(); + } + phys = null; + } } } } } - public StoreDirect(String fileName) { - - this( fileName, - fileName==null || fileName.isEmpty()?Volume.memoryFactory():Volume.fileFactory(), - fileName==null || fileName.isEmpty()?Volume.memoryFactory():Volume.fileFactory(), - false, - false, - CC.DEFAULT_FREE_SPACE_RECLAIM_Q, - false, - 0, - false, - false, - null, - 0 - ); + public StoreDirect(Volume.Factory volFac) { + this(volFac, false,false,5,false,0L); + } + + protected void checkNotDeleted(long indexVal){ + if((indexVal & MASK_PREALLOC)!=0) + throw new DBException.PreallocRecordAccess(); + if((indexVal & MASK_OFFSET)==0) + throw new DBException.RecordNotFound(); } protected void checkHeaders() { @@ -290,9 +284,8 @@ protected void checkHeaders() { } protected void createStructure() { - indexSize = IO_USER_START+LAST_RESERVED_RECID*8+8; - if(CC.PARANOID && ! (indexSize>IO_USER_START)) - throw new AssertionError(); + indexSize = IO_USER_START+ 0*8+8; + assert(indexSize>IO_USER_START); index.ensureAvailable(indexSize); for(int i=0;i0)) - throw new AssertionError(); - if(CC.LOG_STORE && LOG.isLoggable(Level.FINEST)) + assert(recid>0); + if(CC.LOG_STORE) LOG.finest("Preallocate recid=" + recid); return recid; }finally { + newRecidLock.readLock().unlock(); + } + } + + @Override + public void preallocatePut(long recid, @Nullable Serializer serializer, @NotNull R value) { + assert(value!=null); + assert(recid>0); + DataOutput2ByteArray out = serialize(value, serializer); - newRecidLock.readLock().unlock(); + final long ioRecid = IO_USER_START + recid*8; + final Lock lock = locks.writeLock(); + lock.lock(); + try{ + update2(out, ioRecid, true); + }finally{ + lock.unlock(); } + if(CC.LOG_STORE) + LOG.finest("Update recid="+recid+", "+" size="+out.pos+", "+" val="+value+" ser="+serializer ); + } @Override public void preallocate(long[] recids) { - newRecidLock.readLock().lock(); + newRecidLock.readLock().lock(); try{ - structuralLock.lock(); + structuralLock.lock(); try{ for(int i=0;i0)) - throw new AssertionError(); + assert(recids[i]>0); } - if(CC.LOG_STORE && LOG.isLoggable(Level.FINEST)) + if(CC.LOG_STORE) LOG.finest("Preallocate recids="+Arrays.toString(recids)); }finally { - newRecidLock.readLock().unlock(); + newRecidLock.readLock().unlock(); } } @Override public
long put(A value, Serializer serializer) { - if(CC.PARANOID && ! (value!=null)) - throw new AssertionError(); - DataIO.DataOutputByteArray out = serialize(value, serializer); + assert(value!=null); + DataOutput2ByteArray out = serialize(value, serializer); final long ioRecid; newRecidLock.readLock().lock(); - try{ + structuralLock.lock(); + final long[] indexVals; try{ ioRecid = freeIoRecidTake(true) ; indexVals = physAllocate(out.pos,true,false); }finally { structuralLock.unlock(); - } - final Lock lock = locks[Store.lockPos(ioRecid)].writeLock(); + final Lock lock = locks.writeLock(); lock.lock(); try{ put2(out, ioRecid, indexVals); }finally { - lock.unlock(); + lock.unlock(); } }finally { - newRecidLock.readLock().unlock(); + newRecidLock.readLock().unlock(); } long recid = (ioRecid-IO_USER_START)/8; - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - if(CC.LOG_STORE && LOG.isLoggable(Level.FINEST)) + assert(recid>0); + if(CC.LOG_STORE) LOG.finest("Put recid="+recid+", "+" size="+out.pos+", "+" val="+value+" ser="+serializer ); - recycledDataOuts.offer(out); return recid; } - protected void put2(DataIO.DataOutputByteArray out, long ioRecid, long[] indexVals) { - if(CC.PARANOID && ! (locks[Store.lockPos(ioRecid)].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); + protected void put2(DataOutput2ByteArray out, long ioRecid, long[] indexVals) { + assert(locks.writeLock().isHeldByCurrentThread()); + if(out.pos==0){ + index.putLong(ioRecid, INDEX_VAL_ZERO_SIZE); + return; + } index.putLong(ioRecid, indexVals[0]|MASK_ARCHIVE); //write stuff if(indexVals.length==1||indexVals[1]==0){ //is more then one? ie linked @@ -444,8 +448,7 @@ protected void put2(DataIO.DataOutputByteArray out, long ioRecid, long[] indexVa final int c = i==indexVals.length-1 ? 0: 8; final long indexVal = indexVals[i]; final boolean isLast = (indexVal & MASK_LINKED) ==0; - if(CC.PARANOID && ! (isLast==(i==indexVals.length-1))) - throw new AssertionError(); + assert(isLast==(i==indexVals.length-1)); final int size = (int) (indexVal>>>48); final long offset = indexVal&MASK_OFFSET; @@ -465,17 +468,12 @@ protected void put2(DataIO.DataOutputByteArray out, long ioRecid, long[] indexVa @Override public A get(long recid, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); + assert(recid>0); final long ioRecid = IO_USER_START + recid*8; - final Lock lock = locks[Store.lockPos(ioRecid)].readLock(); + final Lock lock = locks.readLock(); lock.lock(); - try{ - final A ret = get2(ioRecid,serializer); - if(CC.LOG_STORE && LOG.isLoggable(Level.FINEST)) - LOG.finest("GET recid="+recid+", "+" ret="+ret+", "+" ser="+serializer ); - return ret; + return get2(ioRecid,serializer); }catch(IOException e){ throw new IOError(e); }finally{ @@ -484,17 +482,19 @@ public A get(long recid, Serializer serializer) { } protected A get2(long ioRecid,Serializer serializer) throws IOException { - if(CC.PARANOID && ! (locks[Store.lockPos(ioRecid)].getWriteHoldCount()==0|| - locks[Store.lockPos(ioRecid)].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); + assert(locks.getWriteHoldCount()==0|| + locks.writeLock().isHeldByCurrentThread()); long indexVal = index.getLong(ioRecid); - if(indexVal == MASK_DISCARD) return null; //preallocated record + checkNotDeleted(indexVal); + if(indexVal == MASK_PREALLOC) throw new DBException.PreallocRecordAccess(); int size = (int) (indexVal>>>48); - DataInput di; + DataInput2Exposed di; long offset = indexVal&MASK_OFFSET; - if((indexVal& MASK_LINKED)==0){ + if(indexVal == INDEX_VAL_ZERO_SIZE) { + di = new DataInput2Exposed(ByteBuffer.allocate(0)); + }else if((indexVal& MASK_LINKED)==0){ //read single record di = phys.getDataInput(offset, size); @@ -506,7 +506,7 @@ protected A get2(long ioRecid,Serializer serializer) throws IOException { byte[] buf = new byte[64]; //read parts into segment for(;;){ - DataInput in = phys.getDataInput(offset + c, size-c); + DataInput2Exposed in = phys.getDataInput(offset + c, size-c); if(buf.length A get2(long ioRecid,Serializer serializer) throws IOException { //is the next part last? c = ((next& MASK_LINKED)==0)? 0 : 8; } - di = new DataIO.DataInputByteArray(buf); + ByteBuffer buf2 = ByteBuffer.wrap(buf); + buf2.limit(pos); + di = new DataInput2Exposed(buf2); size = pos; } return deserialize(serializer, size, di); @@ -529,37 +531,60 @@ protected A get2(long ioRecid,Serializer serializer) throws IOException { @Override - public void update(long recid, A value, Serializer serializer) { - if(CC.PARANOID && ! (value!=null)) - throw new AssertionError(); - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); - DataIO.DataOutputByteArray out = serialize(value, serializer); + public void update(long recid, Serializer serializer, A value) { + assert(value!=null); + assert(recid>0); + DataOutput2ByteArray out = serialize(value, serializer); final long ioRecid = IO_USER_START + recid*8; - final Lock lock = locks[Store.lockPos(ioRecid)].writeLock(); + final Lock lock = locks.writeLock(); lock.lock(); - try{ - update2(out, ioRecid); + update2(out, ioRecid, false); }finally{ lock.unlock(); } - if(CC.LOG_STORE && LOG.isLoggable(Level.FINEST)) + if(CC.LOG_STORE) LOG.finest("Update recid="+recid+", "+" size="+out.pos+", "+" val="+value+" ser="+serializer ); + } + + @Override + public void updateAtomic(long recid, Serializer serializer, Transform r) { + assert(recid>0); + final long ioRecid = IO_USER_START + recid*8; + + final Lock lock = locks.writeLock(); + lock.lock(); + try{ + R old = get2(ioRecid, serializer); + R newRec = r.transform(old); + if(old==newRec) + return; + update2(serialize(newRec, serializer), ioRecid, false); + } catch (IOException e) { + throw new IOError(e); + } finally{ + lock.unlock(); + } - recycledDataOuts.offer(out); } - protected void update2(DataIO.DataOutputByteArray out, long ioRecid) { + protected void update2(DataOutput2ByteArray out, long ioRecid, boolean prealoc) { final long indexVal = index.getLong(ioRecid); final int size = (int) (indexVal>>>48); final boolean linked = (indexVal&MASK_LINKED)!=0; - if(CC.PARANOID && ! (locks[Store.lockPos(ioRecid)].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); + assert(locks.writeLock().isHeldByCurrentThread()); + + if(!prealoc) + checkNotDeleted(indexVal); + else if(indexVal != MASK_PREALLOC){ + throw new DBException.RecordNotPreallocated(); + } - if(!linked && out.pos>0 && size>0 && size2ListIoRecid(size) == size2ListIoRecid(out.pos)){ + if((prealoc || size==0) && out.pos==0){ + index.putLong(ioRecid, INDEX_VAL_ZERO_SIZE); + }else if(!linked && out.pos>0 && size>0 && size2ListIoRecid(size) == size2ListIoRecid(out.pos)){ //size did change, but still fits into this location final long offset = indexVal & MASK_OFFSET; @@ -568,7 +593,9 @@ protected void update2(DataIO.DataOutputByteArray out, long ioRecid) { phys.putData(offset, out.buf, 0, out.pos); }else{ + long[] indexVals = spaceReclaimTrack ? getLinkedRecordsIndexVals(indexVal) : null; + structuralLock.lock(); try{ @@ -592,23 +619,18 @@ protected void update2(DataIO.DataOutputByteArray out, long ioRecid) { put2(out, ioRecid, indexVals); } - if(CC.PARANOID && ! (locks[Store.lockPos(ioRecid)].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); + assert(locks.writeLock().isHeldByCurrentThread()); } @Override - public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) { - if(CC.PARANOID && ! (expectedOldValue!=null && newValue!=null)) - throw new AssertionError(); - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); + public boolean compareAndUpdate(long recid, Serializer serializer, A expectedOldValue, A newValue) { + assert(recid>0); final long ioRecid = IO_USER_START + recid*8; - final Lock lock = locks[Store.lockPos(ioRecid)].writeLock(); + final Lock lock = locks.writeLock(); lock.lock(); - - DataIO.DataOutputByteArray out; + DataOutput2ByteArray out; try{ /* * deserialize old value @@ -627,37 +649,45 @@ public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Se */ out = serialize(newValue, serializer); - update2(out, ioRecid); + update2(out, ioRecid, false); }catch(IOException e){ throw new IOError(e); }finally{ lock.unlock(); } - recycledDataOuts.offer(out); return true; } + @Override + public void verify() { + //TODO verify + } + + @Override + public boolean isEmpty() { + return getMaxRecid()<=1L; + } + @Override public void delete(long recid, Serializer serializer) { - if(CC.PARANOID && ! (recid>0)) - throw new AssertionError(); + assert(recid>0); final long ioRecid = IO_USER_START + recid*8; - final Lock lock = locks[Store.lockPos(ioRecid)].writeLock(); + final Lock lock = locks.writeLock(); lock.lock(); - try{ //get index val and zero it out final long indexVal = index.getLong(ioRecid); + checkNotDeleted(indexVal); + index.putLong(ioRecid,0L|MASK_ARCHIVE); - if(!spaceReclaimTrack) return; //free space is not tracked, so do not mark stuff as free + if(!spaceReclaimTrack || indexVal==INDEX_VAL_ZERO_SIZE) return; //free space is not tracked, so do not mark stuff as free long[] linkedRecords = getLinkedRecordsIndexVals(indexVal); //now lock everything and mark free space structuralLock.lock(); - try{ //free recid freeIoRecidPut(ioRecid); @@ -672,14 +702,49 @@ public void delete(long recid, Serializer serializer) { } } }finally { - structuralLock.unlock(); + structuralLock.unlock(); } }finally{ - lock.unlock(); + lock.unlock(); } } + @Override + public R getAndDelete(long recid, Serializer serializer) { + final long ioRecid = IO_USER_START + recid*8; + final Lock lock = locks.writeLock(); + lock.lock(); + try{ + R ret = get2(ioRecid, serializer); + delete(recid, serializer); + return ret; + } catch (IOException e) { + throw new IOError(e); + } finally { + lock.unlock(); + } + } + + @Override + public boolean compareAndDelete(long recid, Serializer serializer, R expectedOldRecord){ + final long ioRecid = IO_USER_START + recid*8; + final Lock lock = locks.writeLock(); + lock.lock(); + try{ + R ret = get2(ioRecid, serializer); + boolean eq = serializer.equals(ret,expectedOldRecord); + if(eq) + delete(recid, serializer); + return eq; + } catch (IOException e) { + throw new IOError(e); + } finally { + lock.unlock(); + } + } + + protected long[] getLinkedRecordsIndexVals(long indexVal) { long[] linkedRecords = null; @@ -708,8 +773,7 @@ protected long[] getLinkedRecordsIndexVals(long indexVal) { } protected long[] physAllocate(int size, boolean ensureAvail,boolean recursive) { - if(CC.PARANOID && ! (structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); + assert(structuralLock.isHeldByCurrentThread()); if(size==0L) return new long[]{0L}; //append to end of file if(size=IO_FREE_RECID && ioList=IO_FREE_RECID && ioList>>48==0)) - throw new AssertionError(); - if(CC.PARANOID && ! (ioList>=IO_FREE_RECID && ioList<=IO_USER_START)) - throw new AssertionError( "wrong ioList: "+ioList); + assert(structuralLock.isHeldByCurrentThread()); + assert(offset>>>48==0); + assert(ioList>=IO_FREE_RECID && ioList<=IO_USER_START): "wrong ioList: "+ioList; long dataOffset = index.getLong(ioList); long pos = dataOffset>>>48; @@ -1046,8 +1110,7 @@ protected void longStackPut(final long ioList, long offset, boolean recursive){ long next = phys.getLong(dataOffset); long size = next>>>48; next &=MASK_OFFSET; - if(CC.PARANOID && ! (pos+6<=size)) - throw new AssertionError(); + assert(pos+6<=size); if(pos+6==size){ //is current page full? long newPageSize = LONG_STACK_PREF_SIZE; if(ioList == size2ListIoRecid(LONG_STACK_PREF_SIZE)){ @@ -1078,10 +1141,8 @@ protected void longStackPut(final long ioList, long offset, boolean recursive){ protected void freeIoRecidPut(long ioRecid) { - if(CC.PARANOID && ! (ioRecid>IO_USER_START)) - throw new AssertionError(); - if(CC.PARANOID && ! (locks[Store.lockPos(ioRecid)].writeLock().isHeldByCurrentThread())) - throw new AssertionError(); + assert(ioRecid>IO_USER_START); + assert(locks.writeLock().isHeldByCurrentThread()); if(spaceReclaimTrack) longStackPut(IO_FREE_RECID, ioRecid,false); } @@ -1090,16 +1151,14 @@ protected long freeIoRecidTake(boolean ensureAvail){ if(spaceReclaimTrack){ long ioRecid = longStackTake(IO_FREE_RECID,false); if(ioRecid!=0){ - if(CC.PARANOID && ! (ioRecid>IO_USER_START)) - throw new AssertionError(); + assert(ioRecid>IO_USER_START); return ioRecid; } } indexSize+=8; if(ensureAvail) index.ensureAvailable(indexSize); - if(CC.PARANOID && ! (indexSize-8>IO_USER_START)) - throw new AssertionError(); + assert(indexSize-8>IO_USER_START); return indexSize-8; } @@ -1107,20 +1166,23 @@ protected static long size2ListIoRecid(long size){ return IO_FREE_RECID + 8 + ((size-1)/16)*8; } protected void freePhysPut(long indexVal, boolean recursive) { - if(CC.PARANOID && ! (structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); + assert(structuralLock.isHeldByCurrentThread()); long size = indexVal >>>48; - if(CC.PARANOID && ! (size!=0)) - throw new AssertionError(); + assert(size!=0); + indexVal &= MASK_OFFSET; //turn index val into offset + if(physSize == indexVal+roundTo16(size)){ + //if is at end of file, just decrease file size + physSize = indexVal; + return; + } + freeSize+=roundTo16(size); - longStackPut(size2ListIoRecid(size), indexVal & MASK_OFFSET,recursive); + longStackPut(size2ListIoRecid(size), indexVal,recursive); } protected long freePhysTake(int size, boolean ensureAvail, boolean recursive) { - if(CC.PARANOID && ! (structuralLock.isHeldByCurrentThread())) - throw new AssertionError(); - if(CC.PARANOID && ! (size>0)) - throw new AssertionError(); + assert(structuralLock.isHeldByCurrentThread()); + assert(size>0); //check free space if(spaceReclaimReuse){ long ret = longStackTake(size2ListIoRecid(size),recursive); @@ -1136,7 +1198,7 @@ protected long freePhysTake(int size, boolean ensureAvail, boolean recursive) { if(ioList>maxUsedIoList) break; long ret = longStackTake(ioList,recursive); if(ret!=0){ - //found larger record, split in two slices, take first, mark second free + //found larger record, split in two chunks, take first, mark second free final long offset = ret & MASK_OFFSET; long remaining = s - roundTo16(size); @@ -1150,8 +1212,8 @@ protected long freePhysTake(int size, boolean ensureAvail, boolean recursive) { } //not available, increase file size - if((physSize& SLICE_SIZE_MOD_MASK)+size> SLICE_SIZE) - physSize += SLICE_SIZE - (physSize& SLICE_SIZE_MOD_MASK); + if((physSize&CHUNK_SIZE_MOD_MASK)+size>CHUNK_SIZE) + physSize += CHUNK_SIZE - (physSize&CHUNK_SIZE_MOD_MASK); long physSize2 = physSize; physSize = roundTo16(physSize+size); if(ensureAvail) @@ -1168,14 +1230,14 @@ public long getMaxRecid() { @Override public ByteBuffer getRaw(long recid) { //TODO use direct BB - byte[] bb = get(recid, Serializer.BYTE_ARRAY_NOSIZE); + byte[] bb = get(recid, Serializers.BYTE_ARRAY_NOSIZE); if(bb==null) return null; return ByteBuffer.wrap(bb); } @Override public Iterator getFreeRecids() { - return Fun.EMPTY_ITERATOR; //TODO iterate over stack of free recids, without modifying it + return new ArrayList().iterator(); //TODO iterate over stack of free recids, without modifying it } @Override @@ -1194,7 +1256,7 @@ public void updateRaw(long recid, ByteBuffer data) { data.get(b); } //TODO use BB without copying - update(recid, b, Serializer.BYTE_ARRAY_NOSIZE); + update(recid, Serializers.BYTE_ARRAY_NOSIZE, b); } @Override @@ -1227,7 +1289,7 @@ public String calculateStatistics() { for(int size = 16;size=0 && (value>>>6*8)==0)) - throw new AssertionError("value does not fit"); + assert(value>=0 && (value>>>6*8)==0): "value does not fit"; //TODO read/write as integer+short, might be faster putByte(pos + 0, (byte) (0xff & (value >> 40))); putByte(pos + 1, (byte) (0xff & (value >> 32))); @@ -137,8 +147,7 @@ public void putSixLong(long pos, long value) { * Writes packed long at given position and returns number of bytes used. */ public int putPackedLong(long pos, long value) { - if(CC.PARANOID && ! (value>=0)) - throw new AssertionError("negative value"); + assert(value>=0):"negative value"; int ret = 0; @@ -168,69 +177,115 @@ public long getPackedLong(long pos){ throw new AssertionError("Malformed long."); } + /** - * Transfers data from this Volume into target volume. - * If its possible, the implementation should override this method to enable direct memory transfer. - * - * Caller must respect slice boundaries. ie it is not possible to transfer data which cross slice boundaries. - * - * @param inputOffset offset inside this Volume, ie data will be read from this offset - * @param target Volume to copy data into - * @param targetOffset position in target volume where data will be copied into - * @param size size of data to copy + * Factory which creates two/three volumes used by each MapDB Storage Engine */ - public void transferInto(long inputOffset, Volume target, long targetOffset, int size) { - byte[] data = new byte[size]; - try { - getDataInput(inputOffset, size).readFully(data); - }catch(IOException e){ - throw new IOError(e); - } - target.putData(targetOffset,data,0,size); + public static interface Factory { + Volume createIndexVolume(); + Volume createPhysVolume(); } - - public static Volume volumeForFile(File f, boolean useRandomAccessFile, boolean readOnly, long sizeLimit, int sliceShift, int sizeIncrement) { + public static Volume volumeForFile(File f, boolean useRandomAccessFile, boolean readOnly, long sizeLimit, int chunkShift, int sizeIncrement) { + return volumeForFile(f, useRandomAccessFile, readOnly, sizeLimit, chunkShift,sizeIncrement, false); + } + public static Volume volumeForFile(File f, boolean useRandomAccessFile, boolean readOnly, long sizeLimit, int chunkShift, + int sizeIncrement, boolean asyncWriteEnabled) { + return volumeForFile(f, useRandomAccessFile, readOnly, sizeLimit, chunkShift,sizeIncrement, asyncWriteEnabled,false); + } + public static Volume volumeForFile(File f, boolean useRandomAccessFile, boolean readOnly, long sizeLimit, int chunkShift, + int sizeIncrement, boolean asyncWriteEnabled, boolean cleanerHackDisable) { return useRandomAccessFile ? - new FileChannelVol(f, readOnly,sizeLimit, sliceShift, sizeIncrement): - new MappedFileVol(f, readOnly,sizeLimit,sliceShift, sizeIncrement); + new FileChannelVol(f, readOnly,sizeLimit, chunkShift, sizeIncrement): + new MappedFileVol(f, readOnly,sizeLimit,chunkShift, sizeIncrement,asyncWriteEnabled, cleanerHackDisable); } - public static Fun.Function1 fileFactory(){ - return fileFactory(false,false,0,CC.VOLUME_SLICE_SHIFT,0); + public static Factory fileFactory(final File indexFile, final int rafMode, final boolean readOnly, final long sizeLimit, + final int chunkShift, final int sizeIncrement){ + return fileFactory( + indexFile, + rafMode, readOnly, sizeLimit, chunkShift, sizeIncrement, + new File(indexFile.getPath() + StoreDirect.DATA_FILE_EXT)); } - public static Fun.Function1 fileFactory( - final boolean useRandomAccessFile, + public static Factory fileFactory(final File indexFile, + final int rafMode, + final boolean readOnly, + final long sizeLimit, + final int chunkShift, + final int sizeIncrement, + + final File physFile) { + return fileFactory( + indexFile, + rafMode, + readOnly, + sizeLimit, + chunkShift, + sizeIncrement, + physFile, + false, false + ); + } + + + public static Factory fileFactory(final File indexFile, + final int rafMode, + final boolean readOnly, + final long sizeLimit, + final int chunkShift, + final int sizeIncrement, + + final File physFile, + final boolean asyncWriteEnabled) { + return fileFactory( + indexFile, + rafMode, + readOnly, + sizeLimit, + chunkShift, + sizeIncrement, + physFile, + false, false + ); + } + public static Factory fileFactory(final File indexFile, + final int rafMode, final boolean readOnly, final long sizeLimit, - final int sliceShift, - final int sizeIncrement) { - return new Fun.Function1() { + final int chunkShift, + final int sizeIncrement, + + final File physFile, + final boolean asyncWriteEnabled, + final boolean cleanerHackDisable) { + return new Factory() { + @Override + public Volume createIndexVolume() { + return volumeForFile(indexFile, rafMode>1, readOnly, sizeLimit, chunkShift, sizeIncrement, asyncWriteEnabled,cleanerHackDisable); + } + @Override - public Volume run(String file) { - return volumeForFile(new File(file), useRandomAccessFile, - readOnly, sizeLimit, sliceShift, sizeIncrement); + public Volume createPhysVolume() { + return volumeForFile(physFile, rafMode>0, readOnly, sizeLimit, chunkShift, sizeIncrement,asyncWriteEnabled,cleanerHackDisable); } + }; } - public static Fun.Function1 memoryFactory(){ - return memoryFactory(false,0L,CC.VOLUME_SLICE_SHIFT); - } + public static Factory memoryFactory(final boolean useDirectBuffer, final long sizeLimit, final int chunkShift) { + return new Factory() { - public static Fun.Function1 memoryFactory( - final boolean useDirectBuffer, final long sizeLimit, final int sliceShift) { - return new Fun.Function1() { + @Override public synchronized Volume createIndexVolume() { + return new MemoryVol(useDirectBuffer, sizeLimit, chunkShift); + } - @Override - public Volume run(String s) { - return useDirectBuffer? - new MemoryVol(true, sizeLimit, sliceShift): - new ByteArrayVol(sizeLimit, sliceShift); + @Override public synchronized Volume createPhysVolume() { + return new MemoryVol(useDirectBuffer, sizeLimit, chunkShift); } + }; } @@ -243,56 +298,68 @@ public Volume run(String s) { abstract static public class ByteBufferVol extends Volume{ - protected final ReentrantLock growLock = new ReentrantLock(CC.FAIR_LOCKS); + protected final ReentrantLock growLock = new ReentrantLock(); protected final long sizeLimit; protected final boolean hasLimit; - protected final int sliceShift; - protected final int sliceSizeModMask; - protected final int sliceSize; + protected final int chunkShift; + protected final int chunkSizeModMask; + protected final int chunkSize; - protected volatile ByteBuffer[] slices = new ByteBuffer[0]; + protected volatile ByteBuffer[] chunks = new ByteBuffer[0]; protected final boolean readOnly; - protected ByteBufferVol(boolean readOnly, long sizeLimit, int sliceShift) { + /** + * if Async Write is enabled, do not use unmap hack see + * https://github.com/jankotek/MapDB/issues/442 + */ + protected final boolean asyncWriteEnabled; + protected boolean cleanerHackDisabled; + + protected ByteBufferVol(boolean readOnly, long sizeLimit, int chunkShift) { + this(readOnly, sizeLimit, chunkShift, false); + } + + protected ByteBufferVol(boolean readOnly, long sizeLimit, int chunkShift, boolean asyncWriteEnabled) { this.readOnly = readOnly; this.sizeLimit = sizeLimit; - this.sliceShift = sliceShift; - this.sliceSize = 1<< sliceShift; - this.sliceSizeModMask = sliceSize -1; + this.chunkShift = chunkShift; + this.chunkSize = 1<< chunkShift; + this.chunkSizeModMask = chunkSize -1; this.hasLimit = sizeLimit>0; + this.asyncWriteEnabled = asyncWriteEnabled; + this.cleanerHackDisabled = false; } - @Override public final boolean tryAvailable(long offset) { if (hasLimit && offset > sizeLimit) return false; - int slicePos = (int) (offset >>> sliceShift); + int chunkPos = (int) (offset >>> chunkShift); //check for most common case, this is already mapped - if (slicePos < slices.length){ + if (chunkPos < chunks.length){ return true; } growLock.lock(); try{ //check second time - if(slicePos< slices.length) + if(chunkPos< chunks.length) return true; - int oldSize = slices.length; - ByteBuffer[] slices2 = slices; + int oldSize = chunks.length; + ByteBuffer[] chunks2 = chunks; - slices2 = Arrays.copyOf(slices2, Math.max(slicePos+1, slices2.length + slices2.length/1000)); + chunks2 = Arrays.copyOf(chunks2, Math.max(chunkPos+1, chunks2.length + chunks2.length/1000)); - for(int pos=oldSize;pos>> sliceShift)].putLong((int) (offset & sliceSizeModMask), value); + chunks[(int)(offset >>> chunkShift)].putLong((int) (offset & chunkSizeModMask), value); } @Override public final void putInt(final long offset, final int value) { - slices[(int)(offset >>> sliceShift)].putInt((int) (offset & sliceSizeModMask), value); + chunks[(int)(offset >>> chunkShift)].putInt((int) (offset & chunkSizeModMask), value); } @Override public final void putByte(final long offset, final byte value) { - slices[(int)(offset >>> sliceShift)].put((int) (offset & sliceSizeModMask), value); + chunks[(int)(offset >>> chunkShift)].put((int) (offset & chunkSizeModMask), value); } @Override public void putData(final long offset, final byte[] src, int srcPos, int srcSize){ - final ByteBuffer b1 = slices[(int)(offset >>> sliceShift)].duplicate(); - final int bufPos = (int) (offset& sliceSizeModMask); + final ByteBuffer b1 = chunks[(int)(offset >>> chunkShift)].duplicate(); + final int bufPos = (int) (offset&chunkSizeModMask); b1.position(bufPos); b1.put(src, srcPos, srcSize); } @Override public final void putData(final long offset, final ByteBuffer buf) { - final ByteBuffer b1 = slices[(int)(offset >>> sliceShift)].duplicate(); - final int bufPos = (int) (offset& sliceSizeModMask); + final ByteBuffer b1 = chunks[(int)(offset >>> chunkShift)].duplicate(); + final int bufPos = (int) (offset&chunkSizeModMask); //no overlap, so just write the value b1.position(bufPos); b1.put(buf); } - @Override - public void transferInto(long inputOffset, Volume target, long targetOffset, int size) { - final ByteBuffer b1 = slices[(int)(inputOffset >>> sliceShift)].duplicate(); - final int bufPos = (int) (inputOffset& sliceSizeModMask); - - b1.position(bufPos); - b1.limit(bufPos+size); - target.putData(targetOffset,b1); - } - @Override final public long getLong(long offset) { - return slices[(int)(offset >>> sliceShift)].getLong((int) (offset& sliceSizeModMask)); + return chunks[(int)(offset >>> chunkShift)].getLong((int) (offset&chunkSizeModMask)); } @Override final public int getInt(long offset) { - return slices[(int)(offset >>> sliceShift)].getInt((int) (offset& sliceSizeModMask)); + return chunks[(int)(offset >>> chunkShift)].getInt((int) (offset&chunkSizeModMask)); } @Override public final byte getByte(long offset) { - return slices[(int)(offset >>> sliceShift)].get((int) (offset& sliceSizeModMask)); + return chunks[(int)(offset >>> chunkShift)].get((int) (offset&chunkSizeModMask)); } @Override - public final DataIO.DataInputByteBuffer getDataInput(long offset, int size) { - return new DataIO.DataInputByteBuffer(slices[(int)(offset >>> sliceShift)], (int) (offset& sliceSizeModMask)); + public final DataInput2Exposed getDataInput(long offset, int size) { + ByteBuffer buf = chunks[(int)(offset >>> chunkShift)].duplicate(); + int pos = (int) (offset&chunkSizeModMask); + buf.limit(pos+size); + return new DataInput2Exposed(buf, pos); } @Override public boolean isEmpty() { - return slices.length==0; + return chunks.length==0; } @Override @@ -371,10 +431,7 @@ public boolean isSliced(){ return true; } - @Override - public int sliceSize() { - return sliceSize; - } + /** * Hack to unmap MappedByteBuffer. @@ -383,44 +440,41 @@ public int sliceSize() { * Any error is silently ignored (for example SUN API does not exist on Android). */ protected void unmap(MappedByteBuffer b){ - try{ - if(unmapHackSupported){ - - // need to dispose old direct buffer, see bug - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038 - Method cleanerMethod = b.getClass().getMethod("cleaner", new Class[0]); - if(cleanerMethod!=null){ - cleanerMethod.setAccessible(true); - Object cleaner = cleanerMethod.invoke(b); - if(cleaner!=null){ - Method clearMethod = cleaner.getClass().getMethod("clean", new Class[0]); - if(clearMethod!=null) - clearMethod.invoke(cleaner); - } - } - } - }catch(Exception e){ - unmapHackSupported = false; - //TODO exception handling - //Utils.LOG.log(Level.WARNING, "ByteBufferVol Unmap failed", e); - } - } - - private static boolean unmapHackSupported = true; - static{ - try{ - unmapHackSupported = - SerializerPojo.classForName("sun.nio.ch.DirectBuffer")!=null; - }catch(Exception e){ - unmapHackSupported = false; - } +// try{ +// if(unmapHackSupported && !asyncWriteEnabled){ +// +// // need to dispose old direct buffer, see bug +// // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038 +// Method cleanerMethod = b.getClass().getMethod("cleaner", new Class[0]); +// cleanerMethod.setAccessible(true); +// if(cleanerMethod!=null){ +// Object cleaner = cleanerMethod.invoke(b); +// if(cleaner!=null){ +// Method clearMethod = cleaner.getClass().getMethod("clean", new Class[0]); +// if(clearMethod!=null) { +// clearMethod.invoke(cleaner); +// } +// }else{ +// //cleaner is null, try fallback method for readonly buffers +// Method attMethod = b.getClass().getMethod("attachment", new Class[0]); +// attMethod.setAccessible(true); +// Object att = attMethod.invoke(b); +// if(att instanceof MappedByteBuffer) +// unmap((MappedByteBuffer) att); +// } +// } +// } +// }catch(Exception e){ +// unmapHackSupported = false; +// //TODO exception handling +// //Utils.LOG.log(Level.WARNING, "ByteBufferVol Unmap failed", e); +// } } // Workaround for https://github.com/jankotek/MapDB/issues/326 // File locking after .close() on Windows. private static boolean windowsWorkaround = System.getProperty("os.name").toLowerCase().startsWith("win"); - } public static final class MappedFileVol extends ByteBufferVol { @@ -428,27 +482,38 @@ public static final class MappedFileVol extends ByteBufferVol { protected final File file; protected final FileChannel fileChannel; protected final FileChannel.MapMode mapMode; - protected final java.io.RandomAccessFile raf; + protected final RandomAccessFile raf; + + public MappedFileVol(File file, boolean readOnly, long sizeLimit, int chunkShift, int sizeIncrement) { + this(file,readOnly,sizeLimit,chunkShift,sizeIncrement,false,false); + } - public MappedFileVol(File file, boolean readOnly, long sizeLimit, int sliceShift, int sizeIncrement) { - super(readOnly, sizeLimit, sliceShift); + public MappedFileVol(File file, boolean readOnly, long sizeLimit, int chunkShift, + int sizeIncrement, boolean asyncWriteEnabled) { + this(file,readOnly,sizeLimit,chunkShift,sizeIncrement,asyncWriteEnabled,false); + } + public MappedFileVol(File file, boolean readOnly, long sizeLimit, int chunkShift, int sizeIncrement, + boolean asyncWriteEnabled, boolean cleanerHackDisable) { + super(readOnly, sizeLimit, chunkShift, asyncWriteEnabled); this.file = file; this.mapMode = readOnly? FileChannel.MapMode.READ_ONLY: FileChannel.MapMode.READ_WRITE; + this.cleanerHackDisabled = cleanerHackDisable; try { FileChannelVol.checkFolder(file,readOnly); - this.raf = new java.io.RandomAccessFile(file, readOnly?"r":"rw"); + this.raf = new RandomAccessFile(file, readOnly?"r":"rw"); this.fileChannel = raf.getChannel(); final long fileSize = fileChannel.size(); if(fileSize>0){ //map existing data - slices = new ByteBuffer[(int) ((fileSize>>> sliceShift))]; - for(int i=0;i< slices.length;i++){ - slices[i] = makeNewBuffer(1L*i* sliceSize); + int chunksSize = (int) ((Fun.roundUp(fileSize,chunkSize)>>> chunkShift)); + chunks = new ByteBuffer[chunksSize]; + for(int i=0;i=0)) - throw new AssertionError(); - ByteBuffer ret = fileChannel.map(mapMode,offset, sliceSize); - if(mapMode == FileChannel.MapMode.READ_ONLY) { - ret = ret.asReadOnlyBuffer(); + assert((offset&chunkSizeModMask)==0); + assert(offset>=0); + + //write to end of file, to make sure space is allocated, see #442 + if(!readOnly) { + // get file size + long fileSize = fileChannel.size(); + //and get last byte in mapped offset + long lastMappedOffset = Fun.roundUp(offset+1,chunkSize); + + //expand file size, so no file is expanded by writing into mmaped ByteBuffer + if(Fun.roundUp(fileSize, chunkSize)0) { + fileChannel.write(b, lastMappedOffset-1); + } + + //now zero out all newly allocated bytes + b = ByteBuffer.allocate(1024); + for(;fileSize+10240) { + fileChannel.write(b, fileSize+b.position()); + } + b.rewind(); + } + } } + + ByteBuffer ret = fileChannel.map(mapMode,offset,chunkSize); return ret; } catch (IOException e) { throw new IOError(e); @@ -536,42 +623,46 @@ public File getFile() { @Override public void truncate(long size) { - final int maxSize = 1+(int) (size >>> sliceShift); - if(maxSize== slices.length) + final int maxSize = 1+(int) (size >>> chunkShift); + if(maxSize==chunks.length) return; - if(maxSize> slices.length) { + if(maxSize>chunks.length) { ensureAvailable(size); return; } growLock.lock(); try{ - if(maxSize>= slices.length) + if(maxSize>=chunks.length) return; - ByteBuffer[] old = slices; - slices = Arrays.copyOf(slices,maxSize); + ByteBuffer[] old = chunks; + chunks = Arrays.copyOf(chunks,maxSize); //unmap remaining buffers for(int i=maxSize;i=0 && (value>>>6*8)==0): "value does not fit"; try{ @@ -885,11 +978,11 @@ public byte getByte(long offset) { } @Override - public DataIO.DataInputByteBuffer getDataInput(long offset, int size) { + public DataInput2Exposed getDataInput(long offset, int size) { try{ ByteBuffer buf = ByteBuffer.allocate(size); readFully(offset,buf); - return new DataIO.DataInputByteBuffer(buf,0); + return new DataInput2Exposed(buf,0); }catch(IOException e){ throw new IOError(e); } @@ -898,6 +991,7 @@ public DataIO.DataInputByteBuffer getDataInput(long offset, int size) { @Override public void close() { try{ + closed = true; if(channel!=null) channel.close(); channel = null; @@ -912,7 +1006,8 @@ public void close() { @Override public void sync() { try{ - channel.force(true); + if(channel!=null) + channel.force(true); }catch(IOException e){ throw new IOError(e); } @@ -932,11 +1027,6 @@ public void deleteFile() { file.delete(); } - @Override - public int sliceSize() { - return -1; - } - @Override public boolean isSliced() { return false; @@ -950,324 +1040,16 @@ public File getFile() { /** transfer data from one volume to second. Second volume will be expanded if needed*/ public static void volumeTransfer(long size, Volume from, Volume to){ - int bufSize = Math.min(from.sliceSize(),to.sliceSize()); - - if(bufSize<0 || bufSize>1024*1024*128){ - bufSize = 64 * 1024; //something strange, set safe limit - } - to.ensureAvailable(size); + int bufSize = 1024*64; for(long offset=0;offset0; - } - - - @Override - public final boolean tryAvailable(long offset) { - if (hasLimit && offset > sizeLimit) return false; - - int slicePos = (int) (offset >>> sliceShift); - - //check for most common case, this is already mapped - if (slicePos < slices.length){ - return true; - } - - growLock.lock(); - try{ - //check second time - if(slicePos< slices.length) - return true; - - int oldSize = slices.length; - byte[][] slices2 = slices; - - slices2 = Arrays.copyOf(slices2, Math.max(slicePos+1, slices2.length + slices2.length/1000)); - - for(int pos=oldSize;pos>> sliceShift); - if(maxSize== slices.length) - return; - if(maxSize> slices.length) { - ensureAvailable(size); - return; - } - growLock.lock(); - try{ - if(maxSize>= slices.length) - return; - slices = Arrays.copyOf(slices,maxSize); - }finally { - growLock.unlock(); - } - } - - @Override - public void putLong(long offset, long v) { - int pos = (int) (offset & sliceSizeModMask); - byte[] buf = slices[((int) (offset >>> sliceShift))]; - buf[pos++] = (byte) (0xff & (v >> 56)); - buf[pos++] = (byte) (0xff & (v >> 48)); - buf[pos++] = (byte) (0xff & (v >> 40)); - buf[pos++] = (byte) (0xff & (v >> 32)); - buf[pos++] = (byte) (0xff & (v >> 24)); - buf[pos++] = (byte) (0xff & (v >> 16)); - buf[pos++] = (byte) (0xff & (v >> 8)); - buf[pos++] = (byte) (0xff & (v)); - } - - @Override - public void putInt(long offset, int value) { - int pos = (int) (offset & sliceSizeModMask); - byte[] buf = slices[((int) (offset >>> sliceShift))]; - buf[pos++] = (byte) (0xff & (value >> 24)); - buf[pos++] = (byte) (0xff & (value >> 16)); - buf[pos++] = (byte) (0xff & (value >> 8)); - buf[pos++] = (byte) (0xff & (value)); - } - - @Override - public void putByte(long offset, byte value) { - final byte[] b = slices[((int) (offset >>> sliceShift))]; - b[((int) (offset & sliceSizeModMask))] = value; - } - - @Override - public void putData(long offset, byte[] src, int srcPos, int srcSize) { - int pos = (int) (offset & sliceSizeModMask); - byte[] buf = slices[((int) (offset >>> sliceShift))]; - - System.arraycopy(src,srcPos,buf,pos,srcSize); - } - - @Override - public void putData(long offset, ByteBuffer buf) { - int pos = (int) (offset & sliceSizeModMask); - byte[] dst = slices[((int) (offset >>> sliceShift))]; - buf.get(dst, pos, buf.remaining()); - } - - - @Override - public void transferInto(long inputOffset, Volume target, long targetOffset, int size) { - int pos = (int) (inputOffset & sliceSizeModMask); - byte[] buf = slices[((int) (inputOffset >>> sliceShift))]; - - target.putData(targetOffset,buf,pos, size); - } - - @Override - public long getLong(long offset) { - int pos = (int) (offset & sliceSizeModMask); - byte[] buf = slices[((int) (offset >>> sliceShift))]; - - final int end = pos + 8; - long ret = 0; - for (; pos < end; pos++) { - ret = (ret << 8) | (buf[pos] & 0xFF); - } - return ret; - } - - @Override - public int getInt(long offset) { - int pos = (int) (offset & sliceSizeModMask); - byte[] buf = slices[((int) (offset >>> sliceShift))]; - - final int end = pos + 4; - int ret = 0; - for (; pos < end; pos++) { - ret = (ret << 8) | (buf[pos] & 0xFF); - } - return ret; - } - - @Override - public byte getByte(long offset) { - final byte[] b = slices[((int) (offset >>> sliceShift))]; - return b[((int) (offset & sliceSizeModMask))]; - } - - @Override - public DataInput getDataInput(long offset, int size) { - int pos = (int) (offset & sliceSizeModMask); - byte[] buf = slices[((int) (offset >>> sliceShift))]; - return new DataIO.DataInputByteArray(buf,pos); - } - - @Override - public void close() { - slices =null; - } - - @Override - public void sync() { - - } - - - @Override - public boolean isEmpty() { - return slices.length==0; - } - - @Override - public void deleteFile() { - - } - - @Override - public int sliceSize() { - return sliceSize; - } - - @Override - public boolean isSliced() { - return true; - } - - @Override - public File getFile() { - return null; - } - - } - - - public static class ReadOnly extends Volume{ - - protected final Volume vol; - - public ReadOnly(Volume vol) { - this.vol = vol; - } - - @Override - public boolean tryAvailable(long offset) { - return vol.tryAvailable(offset); - } - - @Override - public void truncate(long size) { - throw new IllegalAccessError("read-only"); - } - - @Override - public void putLong(long offset, long value) { - throw new IllegalAccessError("read-only"); - } - - @Override - public void putInt(long offset, int value) { - throw new IllegalAccessError("read-only"); - } - - @Override - public void putByte(long offset, byte value) { - throw new IllegalAccessError("read-only"); - } - - @Override - public void putData(long offset, byte[] src, int srcPos, int srcSize) { - throw new IllegalAccessError("read-only"); - } - - @Override - public void putData(long offset, ByteBuffer buf) { - throw new IllegalAccessError("read-only"); - } - - @Override - public long getLong(long offset) { - return vol.getLong(offset); - } - - @Override - public int getInt(long offset) { - return vol.getInt(offset); - } - - @Override - public byte getByte(long offset) { - return vol.getByte(offset); - } - - @Override - public DataInput getDataInput(long offset, int size) { - return vol.getDataInput(offset,size); - } - - @Override - public void close() { - vol.close(); - } - - @Override - public void sync() { - vol.sync(); - } - - @Override - public int sliceSize() { - return vol.sliceSize(); - } - - @Override - public boolean isEmpty() { - return vol.isEmpty(); - } - - @Override - public void deleteFile() { - throw new IllegalAccessError("read-only"); - } - - @Override - public boolean isSliced() { - return vol.isSliced(); - } - - @Override - public File getFile() { - return vol.getFile(); + DataInput2Exposed input = from.getDataInput(offset, bb); + ByteBuffer buf = input.buf.duplicate(); + buf.position(input.pos); + buf.limit(input.pos+bb); + to.ensureAvailable(offset+bb); + to.putData(offset,buf); } } } diff --git a/src/main/java/org/mapdb/store/li/LiStore.java b/src/main/java/org/mapdb/store/li/LiStore.java new file mode 100644 index 000000000..c3ef58031 --- /dev/null +++ b/src/main/java/org/mapdb/store/li/LiStore.java @@ -0,0 +1,233 @@ +package org.mapdb.store.li; + +import org.jetbrains.annotations.NotNull; +import org.mapdb.DBException; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataInput2ByteBuffer; +import org.mapdb.io.DataOutput2; +import org.mapdb.io.DataOutput2ByteArray; +import org.mapdb.ser.Serializer; +import org.mapdb.store.Store; + +import java.nio.ByteBuffer; +import java.util.LinkedList; +import java.util.Queue; + +import static org.mapdb.store.li.LiUtil.*; + +public class LiStore implements Store { + + private final static int PAGE_SIZE = 1024; + + private final long[] index = new long[100_000]; + + private final Queue freeRecids = new LinkedList<>(); + private int recidTail = 1; + + private final Queue freePages = new LinkedList<>(); + private long pageTail = PAGE_SIZE; + + private final ByteBuffer data = ByteBuffer.allocate(64*1024*1024); + + + + @Override + public long preallocate() { + int recid = allocRecid(); + index[recid] = composeRecordType(R_PREALLOC); + return recid; + } + + @Override + public void preallocatePut(long recid, @NotNull Serializer serializer, @NotNull R record) { + long indexVal = index[(int) recid]; + if(indexVal == R_VOID) + throw new DBException.RecordNotPreallocated(); + int recType = decompIndexValType(indexVal); + if(recType != R_PREALLOC) + throw new DBException.RecordNotPreallocated(); + + long page = allocPage(); + int size = serializeToPage(record, serializer, (int) page); + index[(int) recid] = composeIndexValSmall(size, page); + } + + @Override + public @NotNull long put(@NotNull R record, @NotNull Serializer serializer) { + long page = allocPage(); + int size = serializeToPage(record, serializer, (int) page); + + int recid = allocRecid(); + + index[recid] = composeIndexValSmall(size, page); + return recid; + } + + + protected int serializeToPage(@NotNull R record, @NotNull Serializer serializer, long page) { + DataOutput2 out = new DataOutput2ByteArray(); + serializer.serialize(out, record); + byte[] b = out.copyBytes(); + if(b.length>PAGE_SIZE) + throw new RuntimeException(); + + ByteBuffer bb = data.duplicate(); + bb.position((int) page); + bb.put(b); + return b.length; + } + + private int allocRecid() { + Integer recid = freeRecids.poll(); + if(recid == null) + return recidTail++; + return recid; + } + + private long allocPage() { + Long ret = freePages.poll(); + if(ret==null) { + ret = pageTail; + pageTail+=PAGE_SIZE; + } + return ret; + } + + @Override + public void update(long recid, @NotNull Serializer serializer, @NotNull R updatedRecord) { + long indexVal = index[(int) recid]; + if(indexVal== R_VOID) + throw new DBException.RecordNotFound(); + int recType = decompIndexValType(indexVal); + if(recType == R_PREALLOC) + throw new DBException.PreallocRecordAccess(); + int size = decompIndexValSize(indexVal); + long page = decompIndexValPage(indexVal); + + + int newSize = serializeToPage(updatedRecord, serializer, page); + index[(int) recid] = composeIndexValSmall(newSize, page); + } + + @Override + public void verify() { + + } + + @Override + public void commit() { + + } + + @Override + public void compact() { + + } + + @Override + public boolean isThreadSafe() { + return false; + } + + @Override + public void updateAtomic(long recid, @NotNull Serializer serializer, @NotNull Transform r) { + R rec = get(recid, serializer); + rec = r.transform(rec); + update(recid, serializer, rec); + } + + @Override + public boolean compareAndUpdate(long recid, @NotNull Serializer serializer, @NotNull R expectedOldRecord, @NotNull R updatedRecord) { + R r = get(recid, serializer); + if(!serializer.equals(r,expectedOldRecord)) + return false; + update(recid, serializer, updatedRecord); + return true; + } + + @Override + public boolean compareAndDelete(long recid, @NotNull Serializer serializer, @NotNull R expectedOldRecord) { + R r = get(recid, serializer); + if(!serializer.equals(r,expectedOldRecord)) + return false; + delete(recid, serializer); + return true; + } + + @Override + public void delete(long recid, @NotNull Serializer serializer) { + long indexVal = index[(int) recid]; + if(indexVal==R_VOID) + throw new DBException.RecordNotFound(); + int recType = decompIndexValType(indexVal); + if(recType == R_PREALLOC) + throw new DBException.PreallocRecordAccess(); + int size = decompIndexValSize(indexVal); + long page = decompIndexValPage(indexVal); + + index[(int) recid] = R_VOID; + freeRecids.add((int) recid); + zeroOut(data, page, PAGE_SIZE); + freePages.add(page); + } + + @Override + public @NotNull R getAndDelete(long recid, @NotNull Serializer serializer) { + R r = get(recid, serializer); + delete(recid, serializer); + return r; + } + + @Override + public @NotNull K get(long recid, @NotNull Serializer ser) { + long indexVal = index[(int) recid]; + if(indexVal==R_VOID) + throw new DBException.RecordNotFound(); + int recType = decompIndexValType(indexVal); + if(recType == R_PREALLOC) + throw new DBException.PreallocRecordAccess(); + int size = decompIndexValSize(indexVal); + long page = decompIndexValPage(indexVal); + + ByteBuffer bb = data.duplicate(); + bb.position((int) page); + bb.limit((int) (page+size)); + DataInput2 input = new DataInput2ByteBuffer(bb); + return ser.deserialize(input); + } + + @Override + public void close() { + + } + + @Override + public void getAll(@NotNull GetAllCallback callback) { + ByteBuffer bb = data.duplicate(); + for(int recid = 1; recid>> (5*8)) & 0xFFFF); + } + + public static int decompIndexValType(long indexVal) { + return (int) (indexVal >>> (7*8)); + } + + + public static long composeIndexValSmall(int size, long page) { + return (R_SMALL<< (7*8)) | + (((long)size)<<(5*8)) | + page; + } + + public static final long composeRecordType(long recType){ + return recType<<(7*8); + } + +} diff --git a/src/main/java/org/mapdb/util/Exporter.java b/src/main/java/org/mapdb/util/Exporter.java new file mode 100644 index 000000000..c7ecfe665 --- /dev/null +++ b/src/main/java/org/mapdb/util/Exporter.java @@ -0,0 +1,9 @@ +package org.mapdb.util; + +import org.jetbrains.annotations.NotNull; +import org.mapdb.io.DataOutput2ByteArray; + +public interface Exporter { + + void exportToDataOutput2(@NotNull DataOutput2ByteArray output); +} diff --git a/src/main/java/org/mapdb/util/IO.java b/src/main/java/org/mapdb/util/IO.java new file mode 100644 index 000000000..3d6c4301a --- /dev/null +++ b/src/main/java/org/mapdb/util/IO.java @@ -0,0 +1,37 @@ +package org.mapdb.util; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public class IO { + + public static long readLong(DataInputStream in) throws IOException { + return in.readLong(); + } + + public static int readInt(DataInputStream in) throws IOException { + return in.readInt(); + } + + public static byte[] readByteArray(InputStream is, int size) throws IOException { + byte[] buf = new byte[size]; + int read = is.read(buf, 0, size); + if(read!=size) + throw new IOException("not fully read"); //TODO read fully + return buf; + } + + public static void writeLong(DataOutputStream out, long value) throws IOException { + out.writeLong(value); + } + + public static void writeInt(DataOutputStream out, int value) throws IOException { + out.writeInt(value); + } + + public static void writeByteArray(DataOutputStream out, byte[] buf) throws IOException { + out.write(buf); + } +} diff --git a/src/main/java/org/mapdb/util/JavaUtils.java b/src/main/java/org/mapdb/util/JavaUtils.java new file mode 100644 index 000000000..b01f8c52f --- /dev/null +++ b/src/main/java/org/mapdb/util/JavaUtils.java @@ -0,0 +1,14 @@ +package org.mapdb.util; + +import java.util.Comparator; + +public class JavaUtils { + + + public static final Comparator COMPARABLE_COMPARATOR = new Comparator() { + @Override + public int compare(Comparable o1, Comparable o2) { + return o1.compareTo(o2); + } + }; +} diff --git a/src/main/java/org/mapdb/util/MonoRef.java b/src/main/java/org/mapdb/util/MonoRef.java new file mode 100644 index 000000000..5e5ba7eb6 --- /dev/null +++ b/src/main/java/org/mapdb/util/MonoRef.java @@ -0,0 +1,16 @@ +package org.mapdb.util; + +public class MonoRef { + + public R ref; + + public MonoRef() { + } + + public MonoRef(R ref) { + this.ref = ref; + } + + + +} diff --git a/src/test/java/aaGenTest.kt b/src/test/java/aaGenTest.kt new file mode 100644 index 000000000..dd3e4eac9 --- /dev/null +++ b/src/test/java/aaGenTest.kt @@ -0,0 +1,9 @@ +import org.junit.Test + +class genTest{ + + @Test + fun main(){ + AACodeGen() + } +} \ No newline at end of file diff --git a/src/test/java/examples/Bidi_Map.java b/src/test/java/examples/Bidi_Map.java deleted file mode 100644 index 513cbdcaf..000000000 --- a/src/test/java/examples/Bidi_Map.java +++ /dev/null @@ -1,39 +0,0 @@ -package examples; - -import org.mapdb.Bind; -import org.mapdb.DBMaker; -import org.mapdb.Fun; -import org.mapdb.HTreeMap; - -import java.util.NavigableSet; -import java.util.TreeSet; - -/** - * Simple way to create bidirectional map (can find key for given value) using Binding. - */ -public class Bidi_Map { - - public static void main(String[] args) { - //primary map - HTreeMap map = DBMaker.newTempHashMap(); - - // inverse mapping for primary map - NavigableSet inverseMapping = new TreeSet(Fun.COMPARABLE_ARRAY_COMPARATOR); - //NOTE: you may also use Set provided by MapDB to make it persistent - - // bind inverse mapping to primary map, so it is auto-updated - Bind.mapInverse(map, inverseMapping); - - - map.put(10L,"value2"); - map.put(1111L,"value"); - map.put(1112L,"value"); - map.put(11L,"val"); - - //now find all keys for given value - for(Object[] key: Fun.filter(inverseMapping, "value")){ - System.out.println("Key for 'value' is: "+key[1]); - } - - } -} diff --git a/src/test/java/examples/CacheEntryExpiry.java b/src/test/java/examples/CacheEntryExpiry.java deleted file mode 100644 index 32c2907b7..000000000 --- a/src/test/java/examples/CacheEntryExpiry.java +++ /dev/null @@ -1,66 +0,0 @@ -package examples; - -import org.mapdb.DB; -import org.mapdb.DBMaker; -import org.mapdb.HTreeMap; -import org.mapdb.Store; - -import java.util.Random; -import java.util.concurrent.TimeUnit; - - -/** - * HTreeMap (HashMap) can be used as cache, where items are removed after timeout or when maximal size is reached. - * - * - */ -public class CacheEntryExpiry { - - - - public static void main(String[] args) { - //init off-heap store with 2GB size limit - DB db = DBMaker - .newMemoryDirectDB() //use off-heap memory, on-heap is `.newMemoryDB()` - .sizeLimit(2) //limit store size to 2GB - .transactionDisable() //better performance - .make(); - - //create map, entries are expired if not accessed (get,iterate) for 10 seconds or 30 seconds after 'put' - //There is also maximal size limit to prevent OutOfMemoryException - HTreeMap map = db - .createHashMap("cache") - .expireMaxSize(1000000) - .expireAfterWrite(30, TimeUnit.SECONDS) - .expireAfterAccess(10, TimeUnit.SECONDS) - .make(); - - //load stuff - for(int i = 0;i<100000;i++){ - map.put(i, randomString(1000)); - } - - //one can monitor two space usage numbers: - - //free space in store - long freeSize = Store.forDB(db).getFreeSize(); - - //current size of store (how much memory it has allocated - long currentSize = Store.forDB(db).getCurrSize(); - - - } - - - public static String randomString(int size) { - String chars = "0123456789abcdefghijklmnopqrstuvwxyz !@#$%^&*()_+=-{}[]:\",./<>?|\\"; - StringBuilder b = new StringBuilder(size); - Random r = new Random(); - for(int i=0;i - * MapDB uses LZF compression, there is discussion to support other compression alghorithms - * - */ -public class Compression { - - public static void main(String[] args) { - /* - * first case, just enable storage wide compression for all records. - */ - DB db = DBMaker.newMemoryDB() - .compressionEnable() //this settings enables compression - .make(); - //and now create and use map as usual - Map map = db.getTreeMap("test"); - map.put("some","stuff"); - - - - /* - * Other option is to use compression only for specific part. For example if - * you have large values, you may want to compress them. It may make sense - * not to compress BTree Nodes and Keys. - */ - DB db2 = DBMaker.newMemoryDB().make(); //no store wide compression this time - - //construct value serializier, use default serializier - Serializer valueSerializer = db2.getDefaultSerializer(); - //but wrap it, to compress its output - valueSerializer = new Serializer.CompressionWrapper(valueSerializer); - - //now construct map, with additional options - Map map2 = db2.createTreeMap("test") - .valuesOutsideNodesEnable() // store values outside of BTree Nodes. Faster reads if values are large. - .valueSerializer(valueSerializer) //set our value serializer. - .make(); - - map2.put("some","stuff"); - - - } -} diff --git a/src/test/java/examples/Custom_Value.java b/src/test/java/examples/Custom_Value.java deleted file mode 100644 index cb899ada5..000000000 --- a/src/test/java/examples/Custom_Value.java +++ /dev/null @@ -1,134 +0,0 @@ -package examples; - -import org.mapdb.DB; -import org.mapdb.DBMaker; -import org.mapdb.Serializer; - -import java.io.*; -import java.util.Map; - -/* - * Demonstrates HashMaps with non-standard types of objects as key or value. - */ -public class Custom_Value { - - - /** - * MapDB uses custom serialization which stores class metadata at single place. - * Thanks to it is 10x more efficient than standard Java serialization. - * - * Using custom values in MapDB has three conditions: - * - * 1) classes should be immutable. There is instance cache, background serialization etc - * Modifing your classes after they were inserted into MapDB may leed to unexpected things. - * - * 2) You should implement `Serializable` marker interface. MapDB tries to stay compatible - * with standard Java serialization. - * - * 3) Even your values should implement equalsTo method for CAS (compare-and-swap) operations. - * - */ - public static class Person implements Serializable{ - final String name; - final String city; - - public Person(String n, String c){ - super(); - this.name = n; - this.city = c; - } - - public String getName() { - return name; - } - - public String getCity() { - return city; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Person person = (Person) o; - - if (city != null ? !city.equals(person.city) : person.city != null) return false; - if (name != null ? !name.equals(person.name) : person.name != null) return false; - - return true; - } - - } - - public static void main(String[] args) throws IOException { - - // Open db in temp directory - File f = File.createTempFile("mapdb","temp"); - DB db = DBMaker.newFileDB(f) - .make(); - - // Open or create table - Map dbMap = db.getTreeMap("personAndCity"); - - // Add data - Person bilbo = new Person("Bilbo","The Shire"); - Person sauron = new Person("Sauron","Mordor"); - Person radagast = new Person("Radagast","Crazy Farm"); - - dbMap.put("west",bilbo); - dbMap.put("south",sauron); - dbMap.put("mid",radagast); - - // Commit and close - db.commit(); - db.close(); - - - // - // Second option for using cystom values is to use your own serializer. - // This usually leads to better performance as MapDB does not have to - // analyze the class structure. - // - - class CustomSerializer implements Serializer, Serializable{ - - @Override - public void serialize(DataOutput out, Person value) throws IOException { - out.writeUTF(value.getName()); - out.writeUTF(value.getCity()); - } - - @Override - public Person deserialize(DataInput in, int available) throws IOException { - return new Person(in.readUTF(), in.readUTF()); - } - - @Override - public int fixedSize() { - return -1; - } - - } - - Serializer serializer = new CustomSerializer(); - - DB db2 = DBMaker.newTempFileDB().make(); - - Map map2 = db2.createHashMap("map").valueSerializer(serializer).make(); - - map2.put("North", new Person("Yet another dwarf","Somewhere")); - - db2.commit(); - db2.close(); - - - } - - -} - - - - - diff --git a/src/test/java/examples/Histogram.java b/src/test/java/examples/Histogram.java deleted file mode 100644 index 3752f20e7..000000000 --- a/src/test/java/examples/Histogram.java +++ /dev/null @@ -1,44 +0,0 @@ -package examples; - -import org.mapdb.Bind; -import org.mapdb.DBMaker; -import org.mapdb.Fun; -import org.mapdb.HTreeMap; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * Shows how to split map into categories and count elements in each category - * - * Here we show histogram of an {@code Math.random()}. - * We represent category as string for clarity, but any number or other type could be used - */ -public class Histogram { - - public static void main(String[] args) { - HTreeMap map = DBMaker.newTempHashMap(); - - // histogram, category is a key, count is a value - ConcurrentMap histogram = new ConcurrentHashMap(); //any map will do - - // bind histogram to primary map - // we need function which returns category for each map entry - Bind.histogram(map, histogram, new Fun.Function2(){ - @Override - public String run(Long key, Double value) { - if(value<0.25) return "first quarter"; - else if(value<0.5) return "second quarter"; - else if(value<0.75) return "third quarter"; - else return "fourth quarter"; - } - }); - - //insert some random stuff - for(long key=0;key<1e4;key++){ - map.put(key, Math.random()); - } - - System.out.println(histogram); - } -} diff --git a/src/test/java/examples/Huge_Insert.java b/src/test/java/examples/Huge_Insert.java deleted file mode 100644 index 80574ea33..000000000 --- a/src/test/java/examples/Huge_Insert.java +++ /dev/null @@ -1,115 +0,0 @@ -package examples; - -import org.mapdb.*; - -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.Random; - -/** - * Demonstrate how-to create large BTreeMap using data pump. - * Typical usage is to import data set from external source. - * - * @author Jan Kotek - */ -public class Huge_Insert { - - public static void main(String[] args) throws IOException { - - /** max number of elements to import */ - final long max = (int) 1e6; - - /** - * Open database in temporary directory - */ - File dbFile = File.createTempFile("mapdb","temp"); - DB db = DBMaker - .newFileDB(dbFile) - /** disabling Write Ahead Log makes import much faster */ - .transactionDisable() - .make(); - - - long time = System.currentTimeMillis(); - - /** - * Source of data which randomly generates strings. - * In real world this would return data from file. - */ - Iterator source = new Iterator() { - - long counter = 0; - - @Override public boolean hasNext() { - return counter valueExtractor = new Fun.Function1() { - @Override public Integer run(String s) { - return s.hashCode(); - } - }; - - /** - * Create BTreeMap and fill it with data - */ - Map map = db.createTreeMap("map") - .pumpSource(source,valueExtractor) - //.pumpPresort(100000) // for presorting data we could also use this method - .keySerializer(keySerializer) - .make(); - - - System.out.println("Finished; total time: "+(System.currentTimeMillis()-time)/1000+"s; there are "+map.size()+" items in map"); - db.close(); - - } - - public static String randomString(int size) { - String chars = "0123456789abcdefghijklmnopqrstuvwxyz !@#$%^&*()_+=-{}[]:\",./<>?|\\"; - StringBuilder b = new StringBuilder(size); - Random r = new Random(); - for(int i=0;i record = - db.createAtomicVar("lazyRecord", "aaa", db.getDefaultSerializer()); - - record.set("some value"); - System.out.println(record.get()); - - - // Last option is to use low level Engine storage directly. - // Each stored record gets assigned unique recid (record id), - // which is latter used to get or update record. - // Your code should store only recid as reference to object. - // All MapDB collections are written this way. - - //insert new record - long recid = db.getEngine().put("something", Serializer.STRING_NOSIZE); - - //load record - String lazyString = db.getEngine().get(recid, Serializer.STRING_NOSIZE); - - //update record - db.getEngine().update(recid, "new value", Serializer.STRING_NOSIZE); - - - //I hope this example helped! - db.close(); - - } -} diff --git a/src/test/java/examples/Map_Size_Counter.java b/src/test/java/examples/Map_Size_Counter.java deleted file mode 100644 index a898f2e1b..000000000 --- a/src/test/java/examples/Map_Size_Counter.java +++ /dev/null @@ -1,48 +0,0 @@ -package examples; - -import org.mapdb.*; - -import java.util.Map; - -/** - * Keep tracks of number of items in map. - *

- * {@code Collections.size()} typically requires traversing entire collection in MapDB, but there is optional parameter - * which controls if Map keeps track of its count. - */ -public class Map_Size_Counter { - - public static void main(String[] args) { - - //first option, create Map with counter (NOTE: counter is not on by default) - DB db1 = DBMaker.newTempFileDB().make(); - //hashMap - Map m = db1.createHashMap("map1a") - .counterEnable() /**<> map - - //correct way is to use composite set, where 'map key' is primary key and 'map value' is secondary value - NavigableSet multiMap = db.getTreeSet("test"); - - //optionally you can use set with Delta Encoding. This may save lot of space - multiMap = db.createTreeSet("test2") - .serializer(BTreeKeySerializer.ARRAY2) - .make(); - - multiMap.add(new Object[]{"aa",1}); - multiMap.add(new Object[]{"aa",2}); - multiMap.add(new Object[]{"aa",3}); - multiMap.add(new Object[]{"bb",1}); - - //find all values for a key - for(Object[] l: Fun.filter(multiMap, "aa")){ - System.out.println("value for key 'aa': "+l[1]); - } - - //check if pair exists - - boolean found = multiMap.contains(new Object[]{"bb",1}); - System.out.println("Found: " + found); - - db.close(); - - } -} diff --git a/src/test/java/examples/SQL_Auto_Incremental_Unique_Key.java b/src/test/java/examples/SQL_Auto_Incremental_Unique_Key.java deleted file mode 100644 index 8391b6aac..000000000 --- a/src/test/java/examples/SQL_Auto_Incremental_Unique_Key.java +++ /dev/null @@ -1,41 +0,0 @@ -package examples; - -import org.mapdb.Atomic; -import org.mapdb.DB; -import org.mapdb.DBMaker; - -import java.util.Map; - -/** - * Demonstrates Atomic.Long usage as unique-key generator. - * In SQL terms it demonstrates unique IDs using AUTO_INCREMENT. - * Variable is atomically incremented and persisted after JVM shutdown. - * - */ -public class SQL_Auto_Incremental_Unique_Key { - public static void main(String[] args) { - DB db = DBMaker.newTempFileDB().make(); - - //open or create new map - Map map = db.getTreeMap("map"); - - // open existing or create new Atomic record with given name - // if no record with given name exist, new recid is created with value `0` - Atomic.Long keyinc = db.getAtomicLong("map_keyinc"); - - - // Allocate new unique key to use in map - // Atomic.Long will use `compare-and-swap` operation to atomically store incremented value - // Key values can be used only for single insert - // key == 1 - Long key = keyinc.incrementAndGet(); - map.put(key, "some string"); - - // insert second entry, - // key==2 - map.put(keyinc.incrementAndGet(), "some other string"); - - System.out.println(map); - - } -} diff --git a/src/test/java/examples/Secondary_Key.java b/src/test/java/examples/Secondary_Key.java deleted file mode 100644 index 45757fc3a..000000000 --- a/src/test/java/examples/Secondary_Key.java +++ /dev/null @@ -1,47 +0,0 @@ -package examples; - -import org.mapdb.BTreeMap; -import org.mapdb.Bind; -import org.mapdb.DBMaker; -import org.mapdb.Fun; - -import java.util.NavigableSet; -import java.util.TreeSet; - -/** - * Shows howto use secondary non-unique keys, - */ -public class Secondary_Key { - - public static void main(String[] args) { - - // stores string under id - BTreeMap primary = DBMaker.newTempTreeMap(); - - - // stores value hash from primary map - NavigableSet valueHash = - new TreeSet(Fun.COMPARABLE_ARRAY_COMPARATOR); //any Set will do - - // bind secondary to primary so it contains secondary key - Bind.secondaryKey(primary, valueHash, new Fun.Function2() { - @Override - public Integer run(Long key, String value) { - return value.hashCode(); - } - }); - - - //insert some stuff into primary - primary.put(111L, "some value"); - primary.put(112L, "some value"); - - //shot content of secondary - System.out.println(valueHash); - - //get all keys where value hashCode is N - Iterable ids = Fun.filter(valueHash, 1571230533); - System.out.println(ids.iterator().next()[1]); - - } -} diff --git a/src/test/java/examples/Secondary_Map.java b/src/test/java/examples/Secondary_Map.java deleted file mode 100644 index c7249c616..000000000 --- a/src/test/java/examples/Secondary_Map.java +++ /dev/null @@ -1,36 +0,0 @@ -package examples; - -import org.mapdb.Bind; -import org.mapdb.DBMaker; -import org.mapdb.Fun; -import org.mapdb.HTreeMap; - -import java.util.HashMap; -import java.util.Map; - -/** - * Shows how to create secondary map - * which is synchronized with primary map - */ -public class Secondary_Map { - - public static void main(String[] args) { - HTreeMap primary = DBMaker.newMemoryDB().make().getHashMap("test"); - - // secondary map will hold String.size() from primary map as its value - Map secondary = new HashMap(); //can be normal java map, or MapDB map - - - //Bind maps together. It is one way binding, so changes in primary are reflected in secondary - Bind.secondaryValue(primary, secondary, new Fun.Function2() { - @Override public Integer run(Long key, String value) { - return value.length(); - } - }); - - - primary.put(111L, "just some chars"); - int strSize = secondary.get(111L); - System.out.println(strSize); - } -} diff --git a/src/test/java/examples/Secondary_Values.java b/src/test/java/examples/Secondary_Values.java deleted file mode 100644 index 84f0b6a0f..000000000 --- a/src/test/java/examples/Secondary_Values.java +++ /dev/null @@ -1,62 +0,0 @@ -package examples; - -import org.mapdb.*; - -import java.io.Serializable; -import java.util.NavigableSet; - -/** - * Example demonstrate 1:N relation between two collections. - * Secondary set is updated automatically when primary map is modified. - */ -public class Secondary_Values { - - /** - * Each Person class contains name and coma-separated string of friend names - */ - static class Person implements Serializable{ - final int id; - final String name; - //coma separated list of friends - final String friends; - - Person(int id, String name, String friends) { - this.id = id; - this.name = name; - this.friends = friends; - } - } - - public static void main(String[] args) { - DB db = DBMaker.newMemoryDB().make(); - //list if friends - BTreeMap friends = db.getTreeMap("friends"); - - //secondary collections which lists all friends for given id - NavigableSet id2friends = db.createTreeSet("id2friends") - .serializer(BTreeKeySerializer.ARRAY2) - .makeOrGet(); - - //keep secondary synchronized with primary - Bind.secondaryValues(friends,id2friends, new Fun.Function2() { - @Override - public String[] run(Integer integer, Person person) { - return person.friends.split(","); - } - }); - - //add into primary - friends.put(1, new Person(1,"John","Karin,Peter")); - friends.put(2, new Person(2,"Karin","Peter")); - //secondary now contains [1,Karin], [1,Peter], [2,Peter] - System.out.println(id2friends); - - //list all friends associated with John. This does range query on NavigableMap - for(Object[] k:Fun.filter(id2friends, 1)){ - String name = (String) k[1]; - System.out.println(name); - } - - } - -} diff --git a/src/test/java/examples/Transactions.java b/src/test/java/examples/Transactions.java deleted file mode 100644 index 75b0b7e6b..000000000 --- a/src/test/java/examples/Transactions.java +++ /dev/null @@ -1,89 +0,0 @@ -package examples; - -import org.mapdb.DB; -import org.mapdb.DBMaker; -import org.mapdb.TxMaker; -import org.mapdb.TxRollbackException; - -import java.util.Map; - -/** - * MapDB provides concurrent transactions with Serialized Snapshot Isolation to manage MVCC. - * This example shows how to invoke multiple transactions at the same time. - * It also shows rollback in case of an concurrent update conflict - */ -public class Transactions { - public static void main(String[] args) { - - - //Open Transaction Factory. DBMaker shares most options with single-transaction mode. - TxMaker txMaker = DBMaker - .newMemoryDB() - .makeTxMaker(); - - // Now open first transaction and get map from first transaction - DB tx1 = txMaker.makeTx(); - - //create map from first transactions and fill it with data - Map map1 = tx1.getTreeMap("testMap"); - for(int i=0;i<1e4;i++){ - map1.put(i,"aaa"+i); - } - - //commit first transaction - tx1.commit(); - - // !! IMPORTANT !! - // !! DB transaction can be used only once, - // !! it throws an 'already closed' exception after it was commited/rolledback - // !! IMPORTANT !! - //map1.put(1111,"dqdqwd"); // this will fail - - //open second transaction - DB tx2 = txMaker.makeTx(); - Map map2 = tx2.getTreeMap("testMap"); - - //open third transaction - DB tx3 = txMaker.makeTx(); - Map map3 = tx3.getTreeMap("testMap"); - - //put some stuff into second transactions, observer third map size - System.out.println("map3 size before insert: "+map3.size()); - map2.put(-10, "exists"); - System.out.println("map3 size after insert: "+map3.size()); - - //put some stuff into third transactions, observer second map size - System.out.println("map2 size before insert: "+map2.size()); - map3.put(100000, "exists"); - System.out.println("map2 size after insert: "+map2.size()); - - // so far there was no conflict, since modified Map values lie far away from each other in tree. - // `map2` has new key -10, so inserting -11 into map3 should update the same node - map3.put(-11, "exists"); - // `map2` and `map3` now have conflicting data - tx3.commit(); - System.out.println("Insert -11 into map3 was fine"); - - //tx3 was commited, but tx2 now has conflicting data, so its commit will fail - try{ - tx2.commit(); - throw new Error("Should not be here"); - }catch(TxRollbackException e){ - System.out.println("Tx2 commit failed thanks to conflict, tx2 was rolled back"); - } - - //create yet another transaction and observe result - DB tx4 = txMaker.makeTx(); - Map map4 = tx4.getTreeMap("testMap"); - System.out.println("Map size after commits: "+map4.size()); - System.out.println("Value inserted into tx2 and successfully commited: "+map4.get(-10)); - System.out.println("Value inserted into tx3 before rollback: "+map4.get(100000)); - System.out.println("Value inserted into tx3 which triggered rollback: "+map4.get(-11)); - - //close transaction without modifying anything - tx4.close(); - - //close the entire database - txMaker.close(); - } -} diff --git a/src/test/java/examples/Transactions2.java b/src/test/java/examples/Transactions2.java deleted file mode 100644 index 23df7950a..000000000 --- a/src/test/java/examples/Transactions2.java +++ /dev/null @@ -1,32 +0,0 @@ -package examples; - -import org.mapdb.*; - -import java.util.Map; - -/** - * Demonstrates easier way to execute concurrent transactions. - */ -public class Transactions2 { - - public static void main(String[] args) { - TxMaker txMaker = DBMaker.newMemoryDB().makeTxMaker(); - - // Execute transaction within single block. - txMaker.execute(new TxBlock(){ - @Override public void tx(DB db) throws TxRollbackException { - Map m = db.getHashMap("test"); - m.put("test","test"); - } - }); - - //show result of block execution - DB tx1 = txMaker.makeTx(); - Object val = tx1.getHashMap("test").get("test"); - System.out.println(val); - - tx1.close(); - txMaker.close(); - } - -} diff --git a/src/test/java/examples/TreeMap_Composite_Key.java b/src/test/java/examples/TreeMap_Composite_Key.java deleted file mode 100644 index f0f553f08..000000000 --- a/src/test/java/examples/TreeMap_Composite_Key.java +++ /dev/null @@ -1,121 +0,0 @@ -package examples; - -import org.mapdb.BTreeKeySerializer; -import org.mapdb.DB; -import org.mapdb.DBMaker; -import org.mapdb.Fun; - -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ConcurrentNavigableMap; - -/** - * Demonstrates how-to use multi value keys in BTree. - *

- * MapDB has `sortable tuples`. They allow multi value keys in ordinary TreeMap. - * Values are sorted hierarchically, - * fully indexed query must start on first value and continue on second, third and so on. - */ -public class TreeMap_Composite_Key { - - - /** - * In this example we demonstrate spatial queries on a Map - * filled with Address > Income pairs. - *

- * Address is represented as three-value-tuple. - * First value is Town, second is Street and - * third value is House number - *

- * Java Generics are buggy, so we left out some type annotations for simplicity. - * I would recommend more civilized language with type inference such as Kotlin or Scala. - */ - @SuppressWarnings("rawtypes") - public static void main(String[] args) { - //TODO implement Tuple submaps and reenable this example -// -// //initial values -// String[] towns = {"Galway", "Ennis", "Gort", "Cong", "Tuam"}; -// String[] streets = {"Main Street", "Shop Street", "Second Street", "Silver Strands"}; -// int[] houseNums = {1,2,3,4,5,6,7,8,9,10}; -// -// DB db = DBMaker.newMemoryDB().make(); -// //initialize map -// // note that it uses BTreeKeySerializer.TUPLE3 to minimise disk space used by Map -// ConcurrentNavigableMap map = -// db.createTreeMap("test").keySerializer(BTreeKeySerializer.TUPLE3).make(); -// -// -// //fill with values, use simple permutation so we dont have to include large test data. -// Random r = new Random(41); -// for(String town:towns) -// for(String street:streets) -// for(int houseNum:houseNums){ -// Fun.Tuple3 address = Fun.t3(town, street, houseNum); -// int income = r.nextInt(50000); -// map.put(address, income); -// } -// -// System.out.println("There are "+map.size()+ " houses in total"); //NOTE: map.size() traverses entire map -// -// -// //Lets get all houses in Cong -// //Values are sorted so we can query sub-range (values between lower and upper bound) -// Map -// housesInCong = map.subMap( -// Fun.t3("Cong", null, null), //null is 'negative infinity'; everything else is larger than null -// Fun.t3("Cong", Fun.HI, Fun.HI) // 'HI' is 'positive infinity'; everything else is smaller then 'HI' -// ); -// -// System.out.println("There are "+housesInCong.size()+ " houses in Cong"); -// -// //lets make sum of all salary in Cong -// int total = 0; -// for(Integer salary:housesInCong.values()){ -// total+=salary; -// } -// System.out.println("Salary sum for Cong is: "+total); -// -// -// //Now different query, lets get total salary for all living in town center on 'Main Street', including all towns -// //We could iterate over entire map to get this information, but there is more efficient way. -// //Lets iterate over 'Main Street' in all towns. -// total = 0; -// for(String town:towns){ -// -// Map mainStreetHouses = -// map.subMap( -// Fun.t3(town, "Main Street", null), //use null as LOWEST boundary for house number -// Fun.t3(town, "Main Street", Fun.HI) -// ); -// for(Integer salary:mainStreetHouses.values()){ -// total+=salary; -// } -// } -// System.out.println("Salary sum for all Main Streets is: "+total); -// -// -// //other example, lets remove Ennis/Shop Street from our DB -// map.subMap( -// Fun.t3("Ennis", "Shop Street", null), -// Fun.t3("Ennis", "Shop Street", Fun.HI)) -// .clear(); -// -// - } -} - - -//TODO tuple casting is bit rought, integrate this example -// String name="aa"; -// String session = "aa"; -// long timestamp = 11; -// ConcurrentNavigableMap, List> myMap = new ConcurrentSkipListMap, List>(); -// -// final ConcurrentNavigableMap, List> subMap = myMap -// .subMap((Fun.Tuple6)Fun.t6(session, timestamp, name, null, null, null), -// (Fun.Tuple6)Fun.t6(session, timestamp, name, Fun.HI(), Fun.HI(), Fun.HI())); -// -// final ConcurrentNavigableMap, List> subMap2 = myMap -// .subMap(Fun.t6(session, timestamp, name, (Integer)null, (String)null, (Integer)null), -// Fun.t6(session, timestamp, name, Fun.HI(), Fun.HI(), Fun.HI())); diff --git a/src/test/java/examples/TreeMap_Performance_Tunning.java b/src/test/java/examples/TreeMap_Performance_Tunning.java deleted file mode 100644 index 57464d685..000000000 --- a/src/test/java/examples/TreeMap_Performance_Tunning.java +++ /dev/null @@ -1,98 +0,0 @@ -package examples; - -import org.mapdb.DB; -import org.mapdb.DBMaker; - -import java.io.File; -import java.util.Map; -import java.util.Random; - -/** - * Demonstrates how BTree parameters affects performance. BTreeMap has two key parameters - * which affects its performance: - *

Maximal node size

- * Controls how but BTree node can get, before it splits. - * All keys and values in BTree node are stored and deserialized together. - * Large nodes means fewer disk access (tree structure is shallower), - * but also more data to read (more keys to be deserialized). - * - *

Store values inside node

- * Value may be stored inside or outside of BTree node. - * It is recommended to store large values outside nodes. - * - * - * - *

- * Sample output - *

- *  Node size |  small vals  |  large vals  |  large vals outside node
- *     6      |       25 s   |       89 s   |    49 s   |
- *    18      |       25 s   |      144 s   |    50 s   |
- *    32      |       57 s   |      175 s   |    31 s   |
- *    64      |       53 s   |      231 s   |    49 s   |
- *   120      |       73 s   |       98 s   |    49 s   |
- * 
- */ -public class TreeMap_Performance_Tunning { - - - static final int[] nodeSizes = {6, 18, 32, 64, 120}; - - - public static void main(String[] args) { - Random r = new Random(); - - - - System.out.println(" Node size | small vals | large vals | large vals outside node" ); - - for(int nodeSize:nodeSizes){ - - System.out .print(" "+nodeSize+" |"); - - for(int j=0;j<3;j++){ - - boolean useSmallValues = (j==0); - boolean valueOutsideOfNodes = (j==2); - - DB db = DBMaker - .newFileDB(new File("/mnt/big/adsasd")) - .deleteFilesAfterClose() - .closeOnJvmShutdown() - .transactionDisable() - .cacheSize(10) //use small cache size, to simulate much larger store with relatively small cache. - .make(); - - - Map map = - (valueOutsideOfNodes? - (db.createTreeMap("test").valuesOutsideNodesEnable()): - db.createTreeMap("test")) - .nodeSize(nodeSize) - .make(); - - long startTime = System.currentTimeMillis(); - - for(int i=0;i<1e6;i++){ - long key = r.nextLong(); - String value = useSmallValues? - //small value - "abc"+key: - //large value - "qwdkqwdoqpwfwe-09fewkljklcejewfcklajewjkleawckjlaweklcwelkcwecklwecjwekecklwecklaa" - +"kvlskldvklsdklcklsdvkdflvvvvvvvvvvvvvvvvvvvvvvvsl;kzlkvlksdlkvklsdklvkldsklk" - +key; - map.put(key, value); - } - - System.out.print(" "); - System.out.print((System.currentTimeMillis()-startTime)/1000+" s"); - System.out.print(" |"); - db.close(); - } - System.out.println(""); - } - } - - -} diff --git a/src/test/java/examples/_HelloWorld.java b/src/test/java/examples/_HelloWorld.java deleted file mode 100644 index 0406461ac..000000000 --- a/src/test/java/examples/_HelloWorld.java +++ /dev/null @@ -1,43 +0,0 @@ -package examples; - -import org.mapdb.DB; -import org.mapdb.DBMaker; - -import java.io.File; -import java.io.IOException; -import java.util.concurrent.ConcurrentNavigableMap; - - -/** - * Hello world application to demonstrate storage open, commit and close operations - */ -public class _HelloWorld { - - public static void main(String[] args) throws IOException { - - //Configure and open database using builder pattern. - //All options are available with code auto-completion. - File dbFile = File.createTempFile("mapdb","db"); - DB db = DBMaker.newFileDB(dbFile) - .closeOnJvmShutdown() - .encryptionEnable("password") - .make(); - - //open an collection, TreeMap has better performance then HashMap - ConcurrentNavigableMap map = db.getTreeMap("collectionName"); - - map.put(1,"one"); - map.put(2,"two"); - //map.keySet() is now [1,2] even before commit - - db.commit(); //persist changes into disk - - map.put(3,"three"); - //map.keySet() is now [1,2,3] - db.rollback(); //revert recent changes - //map.keySet() is now [1,2] - - db.close(); - - } -} diff --git a/src/test/java/examples/_TempMap.java b/src/test/java/examples/_TempMap.java deleted file mode 100644 index 0ea303ca6..000000000 --- a/src/test/java/examples/_TempMap.java +++ /dev/null @@ -1,28 +0,0 @@ -package examples; - -import org.mapdb.BTreeMap; -import org.mapdb.DBMaker; - -import java.util.Map; - -/** - * Opens maps backed by file in temporary folder. - * Quick and simple way to get Maps which can handle billions of items. - * All files are deleted after Map is closed or JVM exits (using shutdown hook). - */ -public class _TempMap { - public static void main(String[] args) { - - // open new empty map - // DBMaker will create files in temporary folder and opens it - Map map = DBMaker.newTempTreeMap(); - - //put some stuff into map - //all data are stored in file in temp folder - map.put("aa", "bb"); - map.put("cc", "dd"); - - // After JVM exits files are deleted. - // This map was temporary, there is no way to recover its data ! - } -} diff --git a/src/test/java/harmony/AbstractListTest.java b/src/test/java/harmony/AbstractListTest.java new file mode 100644 index 000000000..1bc85d896 --- /dev/null +++ b/src/test/java/harmony/AbstractListTest.java @@ -0,0 +1,495 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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. + */ + +package harmony; + +import java.util.*; + +public class AbstractListTest extends junit.framework.TestCase { + + static class SimpleList extends AbstractList { + ArrayList arrayList; + + SimpleList() { + this.arrayList = new ArrayList(); + } + + public Object get(int index) { + return this.arrayList.get(index); + } + + public void add(int i, Object o) { + this.arrayList.add(i, o); + } + + public Object remove(int i) { + return this.arrayList.remove(i); + } + + public int size() { + return this.arrayList.size(); + } + } + + /** + * @tests java.util.AbstractList#hashCode() + */ + public void test_hashCode() { + List list = new ArrayList(); + list.add(new Integer(3)); + list.add(new Integer(15)); + list.add(new Integer(5)); + list.add(new Integer(1)); + list.add(new Integer(7)); + int hashCode = 1; + Iterator i = list.iterator(); + while (i.hasNext()) { + Object obj = i.next(); + hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); + } + assertTrue("Incorrect hashCode returned. Wanted: " + hashCode + + " got: " + list.hashCode(), hashCode == list.hashCode()); + } + + /** + * @tests java.util.AbstractList#iterator() + */ + public void test_iterator() { + SimpleList list = new SimpleList(); + list.add(new Object()); + list.add(new Object()); + Iterator it = list.iterator(); + it.next(); + it.remove(); + it.next(); + } + + /** + * @tests java.util.AbstractList#listIterator() + */ + public void test_listIterator() { + Integer tempValue; + List list = new ArrayList(); + list.add(new Integer(3)); + list.add(new Integer(15)); + list.add(new Integer(5)); + list.add(new Integer(1)); + list.add(new Integer(7)); + ListIterator lit = list.listIterator(); + assertTrue("Should not have previous", !lit.hasPrevious()); + assertTrue("Should have next", lit.hasNext()); + tempValue = (Integer) lit.next(); + assertTrue("next returned wrong value. Wanted 3, got: " + tempValue, + tempValue.intValue() == 3); + tempValue = (Integer) lit.previous(); + + SimpleList list2 = new SimpleList(); + list2.add(new Object()); + ListIterator lit2 = list2.listIterator(); + lit2.add(new Object()); + lit2.next(); + + //Regression test for Harmony-5808 + list = new MockArrayList(); + ListIterator it = list.listIterator(); + it.add("one"); + it.add("two"); + assertEquals(2,list.size()); + } + + /** + * @tests java.util.AbstractList#subList(int, int) + */ + public void test_subListII() { + // Test each of the SubList operations to ensure a + // ConcurrentModificationException does not occur on an AbstractList + // which does not update modCount + SimpleList mList = new SimpleList(); + mList.add(new Object()); + mList.add(new Object()); + List sList = mList.subList(0, 2); + sList.add(new Object()); // calls add(int, Object) + sList.get(0); + + sList.add(0, new Object()); + sList.get(0); + + sList.addAll(Arrays.asList(new String[] { "1", "2" })); + sList.get(0); + + sList.addAll(0, Arrays.asList(new String[] { "3", "4" })); + sList.get(0); + + sList.remove(0); + sList.get(0); + + ListIterator lit = sList.listIterator(); + lit.add(new Object()); + lit.next(); + lit.remove(); + lit.next(); + + sList.clear(); // calls removeRange() + sList.add(new Object()); + + // test the type of sublist that is returned + List al = new ArrayList(); + for (int i = 0; i < 10; i++) { + al.add(new Integer(i)); + } + assertTrue( + "Sublist returned should have implemented Random Access interface", + al.subList(3, 7) instanceof RandomAccess); + + List ll = new LinkedList(); + for (int i = 0; i < 10; i++) { + ll.add(new Integer(i)); + } + assertTrue( + "Sublist returned should not have implemented Random Access interface", + !(ll.subList(3, 7) instanceof RandomAccess)); + + } + + /** + * @tests java.util.AbstractList#subList(int, int) + */ + public void test_subList_empty() { + // Regression for HARMONY-389 + List al = new ArrayList(); + al.add("one"); + List emptySubList = al.subList(0, 0); + + try { + emptySubList.get(0); + fail("emptySubList.get(0) should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + emptySubList.set(0, "one"); + fail("emptySubList.set(0,Object) should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // expected + } + + try { + emptySubList.remove(0); + fail("emptySubList.remove(0) should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + class MockArrayList extends AbstractList { + /** + * + */ + private static final long serialVersionUID = 1L; + + ArrayList list = new ArrayList(); + + public E remove(int idx) { + modCount++; + return list.remove(idx); + } + + @Override + public E get(int index) { + return list.get(index); + } + + @Override + public int size() { + return list.size(); + } + + public void add(int idx, E o) { + modCount += 10; + list.add(idx, o); + } + } + + /* + * Regression test for HY-4398 + */ + public void test_iterator_next() { + MockArrayList t = new MockArrayList(); + t.list.add("a"); + t.list.add("b"); + + Iterator it = t.iterator(); + + while (it.hasNext()) { + it.next(); + } + try { + it.next(); + fail("Should throw NoSuchElementException"); + } catch (NoSuchElementException cme) { + // expected + } + + t.add("c"); + try { + it.remove(); + fail("Should throw NoSuchElementException"); + } catch (ConcurrentModificationException cme) { + // expected + } + + it = t.iterator(); + try { + it.remove(); + fail("Should throw IllegalStateException"); + } catch (IllegalStateException ise) { + // expected + } + + Object value = it.next(); + assertEquals("a", value); + } + + /** + * @tests java.util.AbstractList#subList(int, int) + */ + public void test_subList_addAll() { + // Regression for HARMONY-390 + List mainList = new ArrayList(); + Object[] mainObjects = { "a", "b", "c" }; + mainList.addAll(Arrays.asList(mainObjects)); + List subList = mainList.subList(1, 2); + assertFalse("subList should not contain \"a\"", subList.contains("a")); + assertFalse("subList should not contain \"c\"", subList.contains("c")); + assertTrue("subList should contain \"b\"", subList.contains("b")); + + Object[] subObjects = { "one", "two", "three" }; + subList.addAll(Arrays.asList(subObjects)); + assertFalse("subList should not contain \"a\"", subList.contains("a")); + assertFalse("subList should not contain \"c\"", subList.contains("c")); + + Object[] expected = { "b", "one", "two", "three" }; + ListIterator iter = subList.listIterator(); + for (int i = 0; i < expected.length; i++) { + assertTrue("subList should contain " + expected[i], subList + .contains(expected[i])); + assertTrue("should be more elements", iter.hasNext()); + assertEquals("element in incorrect position", expected[i], iter + .next()); + } + } + + protected void doneSuite() {} + + class MockRemoveFailureArrayList extends AbstractList { + + @Override + public E get(int location) { + return null; + } + + @Override + public int size() { + return 0; + } + + public E remove(int idx) { + modCount+=2; + return null; + } + + public int getModCount(){ + return modCount; + } + } + + //test remove for failure by inconsistency of modCount and expectedModCount + public void test_remove(){ + MockRemoveFailureArrayList mrfal = new MockRemoveFailureArrayList(); + Iterator imrfal= mrfal.iterator(); + imrfal.next(); + imrfal.remove(); + try{ + imrfal.remove(); + } + catch(ConcurrentModificationException e){ + fail("Excepted to catch IllegalStateException not ConcurrentModificationException"); + } + catch(IllegalStateException e){ + //Excepted to catch IllegalStateException here + } + } + + public void test_subListII2() { + List holder = new ArrayList(16); + for (int i=0; i<10; i++) { + holder.add(i); + } + + // parent change should cause sublist concurrentmodification fail + List sub = holder.subList(0, holder.size()); + holder.add(11); + try { + sub.size(); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.add(12); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.add(0, 11); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.clear(); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.contains(11); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.get(9); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.indexOf(10); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.isEmpty(); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.iterator(); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.lastIndexOf(10); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.listIterator(); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.listIterator(0); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.remove(0); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.remove(9); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.set(0, 0); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.size(); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.toArray(); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + try { + sub.toString(); + fail("Should throw ConcurrentModificationException."); + } catch (ConcurrentModificationException e) {} + + holder.clear(); + } + + /** + * @tests {@link java.util.AbstractList#indexOf(Object)} + */ + public void test_indexOf_Ljava_lang_Object() { + AbstractList list = new MockArrayList(); + Integer[] array = { 1, 2, 3, 4, 5 }; + list.addAll(Arrays.asList(array)); + + assertEquals("find 0 in the list do not contain 0", -1, list + .indexOf(new Integer(0))); + assertEquals("did not return the right location of element 3", 2, list + .indexOf(new Integer(3))); + assertEquals("find null in the list do not contain null element", -1, + list.indexOf(null)); + list.add(null); + assertEquals("did not return the right location of element null", 5, + list.indexOf(null)); + } + + /** + * @add tests {@link java.util.AbstractList#lastIndexOf(Object)} + */ + public void test_lastIndexOf_Ljava_lang_Object() { + AbstractList list = new MockArrayList(); + Integer[] array = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 }; + list.addAll(Arrays.asList(array)); + + assertEquals("find 6 in the list do not contain 6", -1, list + .lastIndexOf(new Integer(6))); + assertEquals("did not return the right location of element 4", 6, list + .lastIndexOf(new Integer(4))); + assertEquals("find null in the list do not contain null element", -1, + list.lastIndexOf(null)); + list.add(null); + assertEquals("did not return the right location of element null", 10, + list.lastIndexOf(null)); + } + + /** + * @add tests {@link java.util.AbstractList#remove(int)} + * @add tests {@link java.util.AbstractList#set(int, Object)} + */ + public void test_remove_I() { + class MockList extends AbstractList { + private ArrayList list; + + @Override + public E get(int location) { + return list.get(location); + } + + @Override + public int size() { + return list.size(); + } + + } + AbstractList list = new MockList(); + try { + list.remove(0); + fail("should throw UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + list.set(0, null); + fail("should throw UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { + // expected + } + } +} diff --git a/src/test/java/harmony/ArrayListTest.java b/src/test/java/harmony/ArrayListTest.java new file mode 100644 index 000000000..41570a3bf --- /dev/null +++ b/src/test/java/harmony/ArrayListTest.java @@ -0,0 +1,861 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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. + */ +package harmony; + +import java.util.*; + +abstract public class ArrayListTest extends junit.framework.TestCase { + + List alist; + + static Object[] objArray; + { + objArray = new Object[100]; + for (int i = 0; i < objArray.length; i++) + objArray[i] = new Integer(i); + } + + + public abstract List newList(); + + + public List newList(Collection col) { + List list = newList(); + for(E e:col){ + list.add(e); + } + return list; + } + + public List newList(int size) { + return newList(); + } + + /** + * @tests java.util.ArrayList#ArrayList() + */ + public void test_Constructor() { + // Test for method java.util.ArrayList() + new Support_ListTest("", alist){}.runTest(); + + List subList = newList(); + for (int i = -50; i < 150; i++) + subList.add(new Integer(i)); + new Support_ListTest("", subList.subList(50, 150)){}.runTest(); + } + + + /** + * @tests java.util.ArrayList#ArrayList(java.util.Collection) + */ + public void test_ConstructorLjava_util_Collection() { + // Test for method java.util.ArrayList(java.util.Collection) + List al = newList(Arrays.asList(objArray)); + assertTrue("arrayList created from collection has incorrect size", al + .size() == objArray.length); + for (int counter = 0; counter < objArray.length; counter++) + assertEquals( + "arrayList created from collection has incorrect elements", + al.get(counter) , objArray[counter]); + + } + + public void testConstructorWithConcurrentCollection() { + Collection collection = shrinksOnSize("A", "B", "C", "D"); + List list = newList(collection); + assertFalse(list.contains("")); + } + + /** + * @tests java.util.ArrayList#add(int, java.lang.Object) + */ + public void test_addILjava_lang_Object() { + // Test for method void java.util.ArrayList.add(int, java.lang.Object) + Object o; + alist.add(50, o = ""); + assertEquals("Failed to add Object", alist.get(50) , o); + assertEquals("Failed to fix up list after insert", + alist.get(51) , objArray[50] + ); + assertEquals(alist.get(52),objArray[51]); + Object oldItem = alist.get(25); + alist.add(25, "null"); + assertEquals("null", alist.get(25)); + assertEquals("Should have returned the old item from slot 25", alist + .get(26), oldItem); + + alist.add(0, o = ""); + assertEquals("Failed to add Object", alist.get(0), o); + assertEquals(alist.get(1), objArray[0]); + assertEquals(alist.get(2), objArray[1]); + + oldItem = alist.get(0); + alist.add(0, "null"); + assertEquals("null", alist.get(0)); + assertEquals("Should have returned the old item from slot 0", alist + .get(1), oldItem); + + try { + alist.add(-1, ""); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + alist.add(-1, "null"); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + alist.add(alist.size() + 1, ""); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + alist.add(alist.size() + 1, "null"); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + } + + /** + * @tests java.util.ArrayList#add(int, java.lang.Object) + */ + public void test_addILjava_lang_Object_2() { + Object o = ""; + int size = alist.size(); + alist.add(size, o); + assertEquals("Failed to add Object", alist.get(size), o); + assertEquals(alist.get(size - 2), objArray[size - 2]); + assertEquals(alist.get(size - 1), objArray[size - 1]); + + alist.remove(size); + + size = alist.size(); + alist.add(size, "null"); + assertEquals("null", alist.get(size)); + assertEquals(alist.get(size - 2), objArray[size - 2]); + assertEquals(alist.get(size - 1), objArray[size - 1]); + } + + /** + * @tests java.util.ArrayList#add(java.lang.Object) + */ + public void test_addLjava_lang_Object() { + // Test for method boolean java.util.ArrayList.add(java.lang.Object) + Object o = ""; + alist.add(o); + assertEquals("Failed to add Object", alist.get(alist.size() - 1), o); + alist.add("null"); + assertEquals("null", alist.get(alist.size() - 1)); + } + + /** + * @tests java.util.ArrayList#addAll(int, java.util.Collection) + */ + public void test_addAllILjava_util_Collection() { + // Test for method boolean java.util.ArrayList.addAll(int, + // java.util.Collection) + alist.addAll(50, alist); + assertEquals("Returned incorrect size after adding to existing list", + 200, alist.size()); + for (int i = 0; i < 50; i++) + assertEquals("Manipulated elements < index", + alist.get(i) , objArray[i]); + for (int i = 0; i >= 50 && (i < 150); i++) + assertEquals("Failed to ad elements properly", + alist.get(i) , objArray[i - 50]); + for (int i = 0; i >= 150 && (i < 200); i++) + assertEquals("Failed to ad elements properly", + alist.get(i) , objArray[i - 100]); + List listWithNulls = newList(); + listWithNulls.add("null"); + listWithNulls.add("null"); + listWithNulls.add("yoink"); + listWithNulls.add("kazoo"); + listWithNulls.add("null"); + alist.addAll(100, listWithNulls); + assertTrue("Incorrect size: " + alist.size(), alist.size() == 205); + assertEquals("null", alist.get(100)); + assertEquals("null", alist.get(101)); + assertEquals("Item at slot 102 should be 'yoink'", "yoink", alist + .get(102)); + assertEquals("Item at slot 103 should be 'kazoo'", "kazoo", alist + .get(103)); + assertEquals("null", alist.get(104)); + alist.addAll(205, listWithNulls); + assertTrue("Incorrect size2: " + alist.size(), alist.size() == 210); + } + + /** + * @tests java.util.ArrayList#addAll(int, java.util.Collection) + */ + @SuppressWarnings("unchecked") + public void test_addAllILjava_util_Collection_2() { + // Regression for HARMONY-467 + List obj = newList(); + try { + obj.addAll((int) -1, (Collection) null); + fail("IndexOutOfBoundsException expected"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + // Regression for HARMONY-5705 + String[] data = new String[] { "1", "2", "3", "4", "5", "6", "7", "8" }; + List list1 = newList(); + List list2 = newList(); + for (String d : data) { + list1.add(d); + list2.add(d); + list2.add(d); + } + while (list1.size() > 0) + list1.remove(0); + list1.addAll(list2); + assertTrue("The object list is not the same as original list", list1 + .containsAll(list2) + && list2.containsAll(list1)); + + obj = newList(); + for (int i = 0; i < 100; i++) { + if (list1.size() > 0) { + obj.removeAll(list1); + obj.addAll(list1); + } + } + assertTrue("The object list is not the same as original list", obj + .containsAll(list1) + && list1.containsAll(obj)); + + // Regression for Harmony-5799 + list1 = newList(); + list2 = newList(); + int location = 2; + + String[] strings = { "0", "1", "2", "3", "4", "5", "6" }; + int[] integers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + for (int i = 0; i < 7; i++) { + list1.add(strings[i]); + } + for (int i = 0; i < 10; i++) { + list2.add(integers[i]); + } + list1.remove(location); + list1.addAll(location, list2); + + // Inserted elements should be equal to integers array + for (int i = 0; i < integers.length; i++) { + assertEquals(integers[i], list1.get(location + i)); + } + // Elements after inserted location should + // be equals to related elements in strings array + for (int i = location + 1; i < strings.length; i++) { + assertEquals(strings[i], list1.get(i + integers.length - 1)); + } + } + + /** + * @tests java.util.ArrayList#addAll(int, java.util.Collection) + */ + public void test_addAllILjava_util_Collection_3() { + List obj = newList(); + obj.addAll(0, obj); + obj.addAll(obj.size(), obj); + try { + obj.addAll(-1, obj); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + obj.addAll(obj.size() + 1, obj); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + obj.addAll(0, null); + fail("Should throw NullPointerException"); + } catch (NullPointerException e) { + // Excepted + } + + try { + obj.addAll(obj.size() + 1, null); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + obj.addAll((int) -1, (Collection) null); + fail("IndexOutOfBoundsException expected"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + } + + public void test_addAllCollectionOfQextendsE() { + // Regression for HARMONY-539 + // https://issues.apache.org/jira/browse/HARMONY-539 + List alist = newList(); + List blist = newList(); + alist.add("a"); + alist.add("b"); + blist.add("c"); + blist.add("d"); + blist.remove(0); + blist.addAll(0, alist); + assertEquals("a", blist.get(0)); + assertEquals("b", blist.get(1)); + assertEquals("d", blist.get(2)); + } + + /** + * @tests java.util.ArrayList#addAll(java.util.Collection) + */ + public void test_addAllLjava_util_Collection() { + // Test for method boolean + // java.util.ArrayList.addAll(java.util.Collection) + List l = newList(); + l.addAll(alist); + for (int i = 0; i < alist.size(); i++) + assertTrue("Failed to add elements properly", l.get(i).equals( + alist.get(i))); + alist.addAll(alist); + assertEquals("Returned incorrect size after adding to existing list", + 200, alist.size()); + for (int i = 0; i < 100; i++) { + assertTrue("Added to list in incorrect order", alist.get(i).equals( + l.get(i))); + assertTrue("Failed to add to existing list", alist.get(i + 100) + .equals(l.get(i))); + } + Set setWithNulls = new HashSet(); + setWithNulls.add("dasdsa"); + setWithNulls.add("yoink"); + setWithNulls.add("kazoo"); + alist.addAll(100, setWithNulls); + Iterator i = setWithNulls.iterator(); + assertEquals("Item at slot 100 is wrong: " + alist.get(100), alist + .get(100) , i.next()); + assertEquals("Item at slot 101 is wrong: " + alist.get(101), alist + .get(101) , i.next()); + assertEquals("Item at slot 103 is wrong: " + alist.get(102), alist + .get(102) , i.next()); + + try { + alist.addAll(null); + fail("Should throw NullPointerException"); + } catch (NullPointerException e) { + // Excepted + } + + // Regression test for Harmony-3481 + List originalList = newList(12); + for (int j = 0; j < 12; j++) { + originalList.add(j); + } + + originalList.remove(0); + originalList.remove(0); + + List additionalList = newList(11); + for (int j = 0; j < 11; j++) { + additionalList.add(j); + } + assertTrue(originalList.addAll(additionalList)); + assertEquals(21, originalList.size()); + + } + + public void test_ArrayList_addAll_scenario1() { + List arrayListA = newList(); + arrayListA.add(1); + List arrayListB = newList(); + arrayListB.add(1); + arrayListA.addAll(1, arrayListB); + int size = arrayListA.size(); + assertEquals(2, size); + for (int index = 0; index < size; index++) { + assertEquals(1, arrayListA.get(index)); + } + } + + public void test_ArrayList_addAll_scenario2() { + List arrayList = newList(); + arrayList.add(1); + arrayList.addAll(1, arrayList); + int size = arrayList.size(); + assertEquals(2, size); + for (int index = 0; index < size; index++) { + assertEquals(1, arrayList.get(index)); + } + } + + // Regression test for HARMONY-5839 + public void testaddAllHarmony5839() { + Collection coll = Arrays.asList(new String[] { "1", "2" }); + List list = newList(); + list.add("a"); + list.add(0, "b"); + list.add(0, "c"); + list.add(0, "d"); + list.add(0, "e"); + list.add(0, "f"); + list.add(0, "g"); + list.add(0, "h"); + list.add(0, "i"); + + list.addAll(6, coll); + + assertEquals(11, list.size()); + assertFalse(list.contains("")); + } + + /** + * @tests java.util.ArrayList#clear() + */ + public void test_clear() { + // Test for method void java.util.ArrayList.clear() + alist.clear(); + assertEquals("List did not clear", 0, alist.size()); + alist.add("null"); + alist.add("null"); + alist.add("null"); + alist.add("bam"); + alist.clear(); + assertEquals("List with nulls did not clear", 0, alist.size()); + /* + * for (int i = 0; i < alist.size(); i++) assertNull("Failed to clear + * list", alist.get(i)); + */ + + } + + /** + * @tests java.util.ArrayList#contains(java.lang.Object) + */ + public void test_containsLjava_lang_Object() { + // Test for method boolean + // java.util.ArrayList.contains(java.lang.Object) + assertTrue("Returned false for valid element", alist + .contains(objArray[99])); + assertTrue("Returned false for equal element", alist + .contains(new Integer(8))); + assertTrue("Returned true for invalid element", !alist + .contains("")); + assertTrue("Returned true for null but should have returned false", + !alist.contains("")); + alist.add("null"); + assertTrue("Returned false for null but should have returned true", + alist.contains("null")); + } + + /** + * @tests java.util.ArrayList#get(int) + */ + public void test_getI() { + // Test for method java.lang.Object java.util.ArrayList.get(int) + assertEquals("Returned incorrect element", alist.get(22), objArray[22]); + try { + alist.get(8765); + fail("Failed to throw expected exception for index > size"); + } catch (IndexOutOfBoundsException e) { + // Expected + assertNotNull(e.getMessage()); + } + } + + /** + * @tests java.util.ArrayList#indexOf(java.lang.Object) + */ + public void test_indexOfLjava_lang_Object() { + // Test for method int java.util.ArrayList.indexOf(java.lang.Object) + assertEquals("Returned incorrect index", 87, alist + .indexOf(objArray[87])); + assertEquals("Returned index for invalid Object", -1, alist + .indexOf("")); + alist.add(25, "null"); + alist.add(50, "null"); + assertEquals("Wrong indexOf for null. Wanted 25 got: " + + alist.indexOf("null"), alist.indexOf("null") , 25); + } + + /** + * @tests java.util.ArrayList#isEmpty() + */ + public void test_isEmpty() { + // Test for method boolean java.util.ArrayList.isEmpty() + assertTrue("isEmpty returned false for new list", newList() + .isEmpty()); + assertTrue("Returned true for existing list with elements", !alist + .isEmpty()); + } + + /** + * @tests java.util.ArrayList#lastIndexOf(java.lang.Object) + */ + public void test_lastIndexOfLjava_lang_Object() { + // Test for method int java.util.ArrayList.lastIndexOf(java.lang.Object) + alist.add(new Integer(99)); + assertEquals("Returned incorrect index", 100, alist + .lastIndexOf(objArray[99])); + assertEquals("Returned index for invalid Object", -1, alist + .lastIndexOf("")); + alist.add(25, "null"); + alist.add(50, "null"); + assertEquals("Wrong lastIndexOf for null. Wanted 50 got: " + + alist.lastIndexOf("null"), alist.lastIndexOf("null") , 50); + } + + /** + * @tests {@link java.util.ArrayList#removeRange(int, int)} + */ + public void test_removeRange() { + MockArrayList mylist = new MockArrayList(); + mylist.removeRange(0, 0); + + try { + mylist.removeRange(0, 1); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + int[] data = { 1, 2, 3 }; + for (int i = 0; i < data.length; i++) { + mylist.add(i, data[i]); + } + + mylist.removeRange(0, 1); + assertEquals(data[1], mylist.get(0)); + assertEquals(data[2], mylist.get(1)); + + try { + mylist.removeRange(-1, 1); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + mylist.removeRange(0, -1); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + mylist.removeRange(1, 0); + //OpenJDK 11 does not throw exception here, some speed hack +// fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + mylist.removeRange(2, 1); + //OpenJDK 11 does not throw exception here, some speed hack +// fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + } + + /** + * @tests java.util.ArrayList#remove(int) + */ + public void test_removeI() { + // Test for method java.lang.Object java.util.ArrayList.remove(int) + alist.remove(10); + assertEquals("Failed to remove element", -1, alist + .indexOf(objArray[10])); + try { + alist.remove(999); + fail("Failed to throw exception when index out of range"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + ArrayList myList = new ArrayList(alist); + alist.add(25, "dsad"); + alist.add(50, "dqwdw"); + alist.remove(50); + alist.remove(25); + assertTrue("Removing nulls did not work", alist.equals(myList)); + + List list = newList(Arrays.asList(new String[] { "a", "b", "c", + "d", "e", "f", "g" })); + assertEquals("Removed wrong element 1", list.remove(0) , "a"); + assertEquals("Removed wrong element 2", list.remove(4) , "f"); + String[] result = new String[5]; + list.toArray(result); + assertTrue("Removed wrong element 3", Arrays.equals(result, + new String[] { "b", "c", "d", "e", "g" })); + + List l = newList(0); + l.add(""); + l.add(""); + l.remove(0); + l.remove(0); + try { + l.remove(-1); + fail("-1 should cause exception"); + } catch (IndexOutOfBoundsException e) { + // Expected + assertNotNull(e.getMessage()); + } + try { + l.remove(0); + fail("0 should case exception"); + } catch (IndexOutOfBoundsException e) { + // Expected + assertNotNull(e.getMessage()); + } + } + + /** + * @tests java.util.ArrayList#set(int, java.lang.Object) + */ + public void test_setILjava_lang_Object() { + // Test for method java.lang.Object java.util.ArrayList.set(int, + // java.lang.Object) + Object obj; + alist.set(65, obj = ""); + assertEquals("Failed to set object", alist.get(65) , obj); + alist.set(50, "null"); + assertEquals("null", alist.get(50)); + assertTrue("Setting increased the list's size to: " + alist.size(), + alist.size() == 100); + + obj = ""; + alist.set(0, obj); + assertEquals("Failed to set object", alist.get(0) , obj); + + try { + alist.set(-1, obj); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + assertNotNull(e.getMessage()); + } + + try { + alist.set(alist.size(), obj); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + assertNotNull(e.getMessage()); + } + + try { + alist.set(-1, "null"); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + assertNotNull(e.getMessage()); + } + + try { + alist.set(alist.size(), "null"); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Expected + assertNotNull(e.getMessage()); + } + } + + /** + * @tests java.util.ArrayList#size() + */ + public void test_size() { + // Test for method int java.util.ArrayList.size() + assertEquals("Returned incorrect size for exiting list", 100, alist + .size()); + assertEquals("Returned incorrect size for new list", 0, newList() + .size()); + } + + /** + * @tests java.util.ArrayList#toArray() + */ + public void test_toArray() { + // Test for method java.lang.Object [] java.util.ArrayList.toArray() + alist.set(25, 25*2); + alist.set(75, 75*2); + Object[] obj = alist.toArray(); + assertEquals("Returned array of incorrect size", objArray.length, + obj.length); + + for (int i = 0; i < obj.length; i++) { + if ((i == 25) || (i == 75)) + assertEquals(i*2, obj[i]); + else + assertEquals("Returned incorrect array: " + i, + obj[i] , objArray[i]); + } + + } + + /** + * @tests java.util.ArrayList#toArray(java.lang.Object[]) + */ + public void test_toArray$Ljava_lang_Object() { + // Test for method java.lang.Object [] + // java.util.ArrayList.toArray(java.lang.Object []) + alist.set(25, 25*2); + alist.set(75, 75*2); + Integer[] argArray = new Integer[100]; + Object[] retArray; + retArray = alist.toArray(argArray); + assertTrue("Returned different array than passed", retArray == argArray); + argArray = new Integer[1000]; + retArray = alist.toArray(argArray); + assertNull("Failed to set first extra element to null", argArray[alist + .size()]); + for (int i = 0; i < 100; i++) { + if ((i == 25) || (i == 75)) + assertEquals(i*2, retArray[i]); + else + assertEquals("Returned incorrect array: " + i, + retArray[i] , objArray[i]); + } + } + + + + /** + * @test java.util.ArrayList#addAll(int, Collection) + */ + public void test_addAll() { + List list = newList(); + list.add("one"); + list.add("two"); + assertEquals(2, list.size()); + + list.remove(0); + assertEquals(1, list.size()); + + List collection = newList(); + collection.add("1"); + collection.add("2"); + collection.add("3"); + assertEquals(3, collection.size()); + + list.addAll(0, collection); + assertEquals(4, list.size()); + + list.remove(0); + list.remove(0); + assertEquals(2, list.size()); + + collection.add("4"); + collection.add("5"); + collection.add("6"); + collection.add("7"); + collection.add("8"); + collection.add("9"); + collection.add("10"); + collection.add("11"); + collection.add("12"); + + assertEquals(12, collection.size()); + + list.addAll(0, collection); + assertEquals(14, list.size()); + } + + public void testAddAllWithConcurrentCollection() { + List list = newList(); + try { + list.addAll(shrinksOnSize("A", "B", "C", "D")); + assertFalse(list.contains("")); + }catch(ConcurrentModificationException e){ + //expected + } + } + + public void testAddAllAtPositionWithConcurrentCollection() { + List list = newList( + Arrays.asList("A", "B", "C", "D")); + try{ + list.addAll(3, shrinksOnSize("E", "F", "G", "H")); + assertFalse(list.contains("")); + }catch(ConcurrentModificationException e){ + //expected + } + } + + public class MockArrayList extends ArrayList { + public int size() { + return 0; + } + + public void removeRange(int start, int end) { + super.removeRange(start, end); + } + } + + + /** + * Sets up the fixture, for example, open a network connection. This method + * is called before a test is executed. + */ + protected void setUp() throws Exception { + super.setUp(); + alist = newList(); + for (int i = 0; i < objArray.length; i++) + alist.add(objArray[i]); + } + + /** + * Returns a collection that emulates another thread calling remove() each + * time the current thread calls size(). + */ + private Collection shrinksOnSize(T... elements) { + return new HashSet(Arrays.asList(elements)) { + boolean shrink = true; + + @Override + public int size() { + int result = super.size(); + if (shrink) { + Iterator i = iterator(); + i.next(); + i.remove(); + } + return result; + } + + @Override + public Object[] toArray() { + shrink = false; + return super.toArray(); + } + }; + } +} diff --git a/src/test/java/harmony/LinkedListTest.java b/src/test/java/harmony/LinkedListTest.java new file mode 100644 index 000000000..5e61f2bba --- /dev/null +++ b/src/test/java/harmony/LinkedListTest.java @@ -0,0 +1,885 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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. + */ + +package harmony; + +import java.util.*; + + +abstract public class LinkedListTest extends junit.framework.TestCase { + + LinkedList ll; + + LinkedList testList; + + private Object testObjOne; + + private Object testObjTwo; + + private Object testObjThree; + + private Object testObjFour; + + private Object testObjLast; + + static Object[] objArray; + { + objArray = new Object[100]; + for (int i = 0; i < objArray.length; i++) + objArray[i] = new Integer(i); + } + + /** + * @tests java.util.LinkedList#LinkedList() + */ + public void test_Constructor() { + // Test for method java.util.LinkedList() + new Support_ListTest("", ll){}.runTest(); + + LinkedList subList = new LinkedList(); + for (int i = -50; i < 150; i++) + subList.add(new Integer(i)); + new Support_ListTest("", subList.subList(50, 150)){}.runTest(); + } + + /** + * @tests java.util.LinkedList#LinkedList(java.util.Collection) + */ + public void test_ConstructorLjava_util_Collection() { + // Test for method java.util.LinkedList(java.util.Collection) + assertTrue("Incorrect LinkedList constructed", new LinkedList(ll) + .equals(ll)); + } + + /** + * @tests java.util.LinkedList#add(int, java.lang.Object) + */ + public void test_addILjava_lang_Object() { + // Test for method void java.util.LinkedList.add(int, java.lang.Object) + Object o; + ll.add(50, o = "Test"); + assertTrue("Failed to add Object>: " + ll.get(50).toString(), ll + .get(50) == o); + assertTrue("Failed to fix up list after insert", + ll.get(51) == objArray[50] && (ll.get(52) == objArray[51])); + ll.add(50, null); + assertNull("Did not add null correctly", ll.get(50)); + + try { + ll.add(-1, "Test"); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Excepted + } + + try { + ll.add(-1, null); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Excepted + } + + try { + ll.add(ll.size() + 1, "Test"); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Excepted + } + + try { + ll.add(ll.size() + 1, null); + fail("Should throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException e) { + // Excepted + } + } + + /** + * @tests java.util.LinkedList#add(java.lang.Object) + */ + public void test_addLjava_lang_Object() { + // Test for method boolean java.util.LinkedList.add(java.lang.Object) + Object o; + ll.add(o = new Object()); + assertTrue("Failed to add Object", ll.getLast() == o); + ll.add(null); + assertNull("Did not add null correctly", ll.get(ll.size() - 1)); + } + + /** + * @tests java.util.LinkedList#addAll(int, java.util.Collection) + */ + public void test_addAllILjava_util_Collection() { + // Test for method boolean java.util.LinkedList.addAll(int, + // java.util.Collection) + ll.addAll(50, (Collection) ll.clone()); + assertEquals("Returned incorrect size after adding to existing list", 200, ll + .size()); + for (int i = 0; i < 50; i++) + assertTrue("Manipulated elements < index", ll.get(i) == objArray[i]); + for (int i = 0; i >= 50 && (i < 150); i++) + assertTrue("Failed to ad elements properly", + ll.get(i) == objArray[i - 50]); + for (int i = 0; i >= 150 && (i < 200); i++) + assertTrue("Failed to ad elements properly", + ll.get(i) == objArray[i - 100]); + List myList = new LinkedList(); + myList.add(null); + myList.add("Blah"); + myList.add(null); + myList.add("Booga"); + myList.add(null); + ll.addAll(50, myList); + assertNull("a) List w/nulls not added correctly", ll.get(50)); + assertEquals("b) List w/nulls not added correctly", + "Blah", ll.get(51)); + assertNull("c) List w/nulls not added correctly", ll.get(52)); + assertEquals("d) List w/nulls not added correctly", + "Booga", ll.get(53)); + assertNull("e) List w/nulls not added correctly", ll.get(54)); + + try { + ll.addAll(50, null); + fail("Should throw NullPointerException"); + } catch (NullPointerException e) { + // Excepted + } + } + + /** + * @tests java.util.LinkedList#addAll(int, java.util.Collection) + */ + public void test_addAllILjava_util_Collection_2() { + // Regression for HARMONY-467 + LinkedList obj = new LinkedList(); + try { + obj.addAll(-1, (Collection) null); + fail("IndexOutOfBoundsException expected"); + } catch (IndexOutOfBoundsException e) { + } + } + + /** + * @tests java.util.LinkedList#addAll(java.util.Collection) + */ + public void test_addAllLjava_util_Collection() { + // Test for method boolean + // java.util.LinkedList.addAll(java.util.Collection) + List l = new ArrayList(); + l.addAll((Collection) ll.clone()); + for (int i = 0; i < ll.size(); i++) + assertTrue("Failed to add elements properly", l.get(i).equals( + ll.get(i))); + ll.addAll((Collection) ll.clone()); + assertEquals("Returned incorrect siZe after adding to existing list", 200, ll + .size()); + for (int i = 0; i < 100; i++) { + assertTrue("Added to list in incorrect order", ll.get(i).equals( + l.get(i))); + assertTrue("Failed to add to existing list", ll.get(i + 100) + .equals(l.get(i))); + } + List myList = new LinkedList(); + myList.add(null); + myList.add("Blah"); + myList.add(null); + myList.add("Booga"); + myList.add(null); + ll.addAll(myList); + assertNull("a) List w/nulls not added correctly", ll.get(200)); + assertEquals("b) List w/nulls not added correctly", + "Blah", ll.get(201)); + assertNull("c) List w/nulls not added correctly", ll.get(202)); + assertEquals("d) List w/nulls not added correctly", + "Booga", ll.get(203)); + assertNull("e) List w/nulls not added correctly", ll.get(204)); + + try { + ll.addAll(null); + fail("Should throw NullPointerException"); + } catch (NullPointerException e) { + // Excepted + } + } + + public void test_addAll_Self_Ljava_util_Collection() { + LinkedList linkedList = new LinkedList(); + linkedList.addLast(1); + assertEquals(1, linkedList.size()); + assertTrue(linkedList.addAll(linkedList)); + assertEquals(2, linkedList.size()); + } + + public void test_addAll_Self_ILjava_util_Collection() { + LinkedList linkedList = new LinkedList(); + linkedList.addLast(1); + assertEquals(1, linkedList.size()); + assertTrue(linkedList.addAll(1, linkedList)); + assertEquals(2, linkedList.size()); + } + + /** + * @tests java.util.LinkedList#addFirst(java.lang.Object) + */ + public void test_addFirstLjava_lang_Object() { + // Test for method void java.util.LinkedList.addFirst(java.lang.Object) + Object o; + ll.addFirst(o = new Object()); + assertTrue("Failed to add Object", ll.getFirst() == o); + ll.addFirst(null); + assertNull("Failed to add null", ll.getFirst()); + } + + /** + * @tests java.util.LinkedList#addLast(java.lang.Object) + */ + public void test_addLastLjava_lang_Object() { + // Test for method void java.util.LinkedList.addLast(java.lang.Object) + Object o; + ll.addLast(o = new Object()); + assertTrue("Failed to add Object", ll.getLast() == o); + ll.addLast(null); + assertNull("Failed to add null", ll.getLast()); + } + + /** + * @tests java.util.LinkedList#clear() + */ + public void test_clear() { + // Test for method void java.util.LinkedList.clear() + ll.clear(); + for (int i = 0; i < ll.size(); i++) + assertNull("Failed to clear list", ll.get(i)); + } + + /** + * @tests java.util.LinkedList#clone() + */ + public void test_clone() { + // Test for method java.lang.Object java.util.LinkedList.clone() + Object x = ll.clone(); + assertTrue("Cloned list was inequal to cloned", x.equals(ll)); + for (int i = 0; i < ll.size(); i++) + assertTrue("Cloned list contains incorrect elements", ll.get(i) + .equals(((LinkedList) x).get(i))); + ll.addFirst(null); + x = ll.clone(); + assertTrue("List with a null did not clone properly", ll.equals(x)); + } + + /** + * @tests java.util.LinkedList#contains(java.lang.Object) + */ + public void test_containsLjava_lang_Object() { + // Test for method boolean + // java.util.LinkedList.contains(java.lang.Object) + assertTrue("Returned false for valid element", ll + .contains(objArray[99])); + assertTrue("Returned false for equal element", ll.contains(new Integer( + 8))); + assertTrue("Returned true for invalid element", !ll + .contains(new Object())); + assertTrue("Should not contain null", !ll.contains(null)); + ll.add(25, null); + assertTrue("Should contain null", ll.contains(null)); + } + + /** + * @tests java.util.LinkedList#get(int) + */ + public void test_getI() { + // Test for method java.lang.Object java.util.LinkedList.get(int) + assertTrue("Returned incorrect element", ll.get(22) == objArray[22]); + try { + ll.get(8765); + fail("Failed to throw expected exception for index > size"); + } catch (IndexOutOfBoundsException e) { + } + } + + /** + * @tests {@link java.util.LinkedList#peek()} + */ + public void test_peek() { + LinkedList list = new LinkedList(); + + assertNull("Should return null if this list is empty", list.peek()); + + assertEquals("Returned incorrect first element", ll.peek(),objArray[0]); + assertEquals("Peek remove the head (first element) of this list", ll.getFirst(), objArray[0]); + } + + /** + * @tests java.util.LinkedList#getFirst() + */ + public void test_getFirst() { + // Test for method java.lang.Object java.util.LinkedList.getFirst() + assertTrue("Returned incorrect first element", ll.getFirst().equals( + objArray[0])); + + LinkedList list = new LinkedList(); + try { + list.getFirst(); + fail("Should throw NoSuchElementException"); + } catch (NoSuchElementException e) { + // Excepted + } + } + + /** + * @tests java.util.LinkedList#getLast() + */ + public void test_getLast() { + // Test for method java.lang.Object java.util.LinkedList.getLast() + assertTrue("Returned incorrect first element", ll.getLast().equals( + objArray[objArray.length - 1])); + + LinkedList list = new LinkedList(); + try { + list.getLast(); + fail("Should throw NoSuchElementException"); + } catch (NoSuchElementException e) { + // Excepted + } + } + + /** + * @tests java.util.LinkedList#indexOf(java.lang.Object) + */ + public void test_indexOfLjava_lang_Object() { + // Test for method int java.util.LinkedList.indexOf(java.lang.Object) + assertEquals("Returned incorrect index", 87, ll.indexOf(objArray[87])); + assertEquals("Returned index for invalid Object", -1, ll + .indexOf(new Object())); + ll.add(20, null); + ll.add(24, null); + assertTrue("Index of null should be 20, but got: " + ll.indexOf(null), + ll.indexOf(null) == 20); + } + + /** + * @tests java.util.LinkedList#lastIndexOf(java.lang.Object) + */ + public void test_lastIndexOfLjava_lang_Object() { + // Test for method int + // java.util.LinkedList.lastIndexOf(java.lang.Object) + ll.add(new Integer(99)); + assertEquals("Returned incorrect index", + 100, ll.lastIndexOf(objArray[99])); + assertEquals("Returned index for invalid Object", -1, ll + .lastIndexOf(new Object())); + ll.add(20, null); + ll.add(24, null); + assertTrue("Last index of null should be 20, but got: " + + ll.lastIndexOf(null), ll.lastIndexOf(null) == 24); + } + + /** + * @tests java.util.LinkedList#listIterator(int) + */ + public void test_listIteratorI() { + // Test for method java.util.ListIterator + // java.util.LinkedList.listIterator(int) + ListIterator i = ll.listIterator(); + Object elm; + int n = 0; + while (i.hasNext()) { + if (n == 0 || n == objArray.length - 1) { + if (n == 0) + assertTrue("First element claimed to have a previous", !i + .hasPrevious()); + if (n == objArray.length) + assertTrue("Last element claimed to have next", !i + .hasNext()); + } + elm = i.next(); + assertTrue("Iterator returned elements in wrong order", + elm == objArray[n]); + if (n > 0 && n < objArray.length - 1) { + assertTrue("Next index returned incorrect value", + i.nextIndex() == n + 1); + assertTrue("previousIndex returned incorrect value : " + + i.previousIndex() + ", n val: " + n, i + .previousIndex() == n); + } + ++n; + } + List myList = new LinkedList(); + myList.add(null); + myList.add("Blah"); + myList.add(null); + myList.add("Booga"); + myList.add(null); + ListIterator li = myList.listIterator(); + assertTrue("li.hasPrevious() should be false", !li.hasPrevious()); + assertNull("li.next() should be null", li.next()); + assertTrue("li.hasPrevious() should be true", li.hasPrevious()); + assertNull("li.prev() should be null", li.previous()); + assertNull("li.next() should be null", li.next()); + assertEquals("li.next() should be Blah", "Blah", li.next()); + assertNull("li.next() should be null", li.next()); + assertEquals("li.next() should be Booga", "Booga", li.next()); + assertTrue("li.hasNext() should be true", li.hasNext()); + assertNull("li.next() should be null", li.next()); + assertTrue("li.hasNext() should be false", !li.hasNext()); + } + + /** + * @tests java.util.LinkedList#remove(int) + */ + public void test_removeI() { + // Test for method java.lang.Object java.util.LinkedList.remove(int) + ll.remove(10); + assertEquals("Failed to remove element", -1, ll.indexOf(objArray[10])); + try { + ll.remove(999); + fail("Failed to throw expected exception when index out of range"); + } catch (IndexOutOfBoundsException e) { + // Correct + } + + ll.add(20, null); + ll.remove(20); + assertNotNull("Should have removed null", ll.get(20)); + } + + /** + * @tests java.util.LinkedList#remove(java.lang.Object) + */ + public void test_removeLjava_lang_Object() { + // Test for method boolean java.util.LinkedList.remove(java.lang.Object) + assertTrue("Failed to remove valid Object", ll.remove(objArray[87])); + assertTrue("Removed invalid object", !ll.remove(new Object())); + assertEquals("Found Object after removal", -1, ll.indexOf(objArray[87])); + ll.add(null); + ll.remove(null); + assertTrue("Should not contain null afrer removal", !ll.contains(null)); + } + + /** + * @tests java.util.LinkedList#removeFirst() + */ + public void test_removeFirst() { + // Test for method java.lang.Object java.util.LinkedList.removeFirst() + ll.removeFirst(); + assertTrue("Failed to remove first element", + ll.getFirst() != objArray[0]); + + LinkedList list = new LinkedList(); + try { + list.removeFirst(); + fail("Should throw NoSuchElementException"); + } catch (NoSuchElementException e) { + // Excepted + } + } + + /** + * @tests java.util.LinkedList#removeLast() + */ + public void test_removeLast() { + // Test for method java.lang.Object java.util.LinkedList.removeLast() + ll.removeLast(); + assertTrue("Failed to remove last element", + ll.getLast() != objArray[objArray.length - 1]); + + LinkedList list = new LinkedList(); + try { + list.removeLast(); + fail("Should throw NoSuchElementException"); + } catch (NoSuchElementException e) { + // Excepted + } + } + + /** + * @tests java.util.LinkedList#set(int, java.lang.Object) + */ + public void test_setILjava_lang_Object() { + // Test for method java.lang.Object java.util.LinkedList.set(int, + // java.lang.Object) + Object obj; + ll.set(65, obj = new Object()); + assertTrue("Failed to set object", ll.get(65) == obj); + } + + /** + * @tests java.util.LinkedList#size() + */ + public void test_size() { + // Test for method int java.util.LinkedList.size() + assertTrue("Returned incorrect size", ll.size() == objArray.length); + ll.removeFirst(); + assertTrue("Returned incorrect size", ll.size() == objArray.length - 1); + } + + /** + * @tests java.util.LinkedList#toArray() + */ + public void test_toArray() { + // Test for method java.lang.Object [] java.util.LinkedList.toArray() + ll.add(null); + Object[] obj = ll.toArray(); + assertEquals("Returned array of incorrect size", objArray.length + 1, obj.length); + + for (int i = 0; i < obj.length - 1; i++) + assertTrue("Returned incorrect array: " + i, obj[i] == objArray[i]); + assertNull("Returned incorrect array--end isn't null", + obj[obj.length - 1]); + } + + /** + * @tests java.util.LinkedList#toArray(java.lang.Object[]) + */ + public void test_toArray$Ljava_lang_Object() { + // Test for method java.lang.Object [] + // java.util.LinkedList.toArray(java.lang.Object []) + Integer[] argArray = new Integer[100]; + Object[] retArray; + retArray = ll.toArray(argArray); + assertTrue("Returned different array than passed", retArray == argArray); + List retList = new LinkedList(Arrays.asList(retArray)); + Iterator li = ll.iterator(); + Iterator ri = retList.iterator(); + while (li.hasNext()) + assertTrue("Lists are not equal", li.next() == ri.next()); + argArray = new Integer[1000]; + retArray = ll.toArray(argArray); + assertNull("Failed to set first extra element to null", argArray[ll + .size()]); + for (int i = 0; i < ll.size(); i++) + assertTrue("Returned incorrect array: " + i, + retArray[i] == objArray[i]); + ll.add(50, null); + argArray = new Integer[101]; + retArray = ll.toArray(argArray); + assertTrue("Returned different array than passed", retArray == argArray); + retArray = ll.toArray(argArray); + assertTrue("Returned different array than passed", retArray == argArray); + retList = new LinkedList(Arrays.asList(retArray)); + li = ll.iterator(); + ri = retList.iterator(); + while (li.hasNext()) + assertTrue("Lists are not equal", li.next() == ri.next()); + } + + /** + * @tests {@link java.util.LinkedList#offer(Object)} + */ + public void test_offer() { + int origSize = ll.size(); + assertTrue("offer() should return true'", ll.offer(objArray[0])); + assertEquals("offer() should add an element as the last one", origSize, ll.lastIndexOf(objArray[0])); + } + + /** + * @tests {@link java.util.LinkedList#poll()} + */ + public void test_poll() { + assertEquals("should return the head", objArray[0], ll.poll()); + LinkedList list = new LinkedList(); + assertNull("should return 'null' if list is empty", list.poll()); + } + + /** + * @tests {@link java.util.LinkedList#remove()} + */ + public void test_remove() { + for (int i = 0; i < objArray.length; i++) { + assertEquals("should remove the head", objArray[i], ll.remove()); + } + assertEquals("should be empty", 0, ll.size()); + try { + ll.remove(); + fail("NoSuchElementException is expected when removing from the empty list"); + } catch (NoSuchElementException e) { + //-- expected + } + } + + /** + * @tests {@link java.util.LinkedList#element()} + */ + public void test_element() { + assertEquals("should return the head", objArray[0], ll.element()); + assertEquals("element() should remove nothing", objArray.length, ll.size()); + try { + new LinkedList().remove(); + fail("NoSuchElementException is expected when the list is empty"); + } catch (NoSuchElementException e) { + //-- expected + } + } + + /** + * @tests {@link java.util.LinkedList#removeFirstOccurrence(Object)} + */ + public void test_removeFirstOccurrence() throws Exception { + assertTrue(testList.offerLast(testObjOne)); + assertTrue(testList.offerLast(testObjTwo)); + assertTrue(testList.offerLast(testObjOne)); + assertTrue(testList.offerLast(testObjThree)); + assertTrue(testList.offerLast(testObjOne)); + assertEquals(5, testList.size()); + assertTrue(testList.removeFirstOccurrence(testObjOne)); + assertFalse(testList.removeFirstOccurrence(testObjFour)); + assertEquals(testObjTwo, testList.peekFirst()); + assertEquals(testObjOne, testList.peekLast()); + assertEquals(4, testList.size()); + assertTrue(testList.removeFirstOccurrence(testObjOne)); + assertEquals(3, testList.size()); + assertEquals(testObjOne, testList.peekLast()); + assertTrue(testList.removeFirstOccurrence(testObjOne)); + assertEquals(2, testList.size()); + assertEquals(testObjThree, testList.peekLast()); + assertFalse(testList.removeFirstOccurrence(testObjOne)); + } + + /** + * @tests {@link java.util.LinkedList#removeLastOccurrence(Object)} + */ + public void test_removeLastOccurrence() throws Exception { + assertTrue(testList.offerLast(testObjOne)); + assertTrue(testList.offerLast(testObjTwo)); + assertTrue(testList.offerLast(testObjOne)); + assertTrue(testList.offerLast(testObjThree)); + assertTrue(testList.offerLast(testObjOne)); + assertEquals(5, testList.size()); + assertTrue(testList.removeLastOccurrence(testObjOne)); + assertFalse(testList.removeLastOccurrence(testObjFour)); + assertEquals(testObjOne, testList.peekFirst()); + assertEquals(testObjThree, testList.peekLast()); + assertEquals(4, testList.size()); + assertTrue(testList.removeLastOccurrence(testObjOne)); + assertEquals(3, testList.size()); + assertEquals(testObjOne, testList.peekFirst()); + assertEquals(testObjThree, testList.peekLast()); + assertTrue(testList.removeLastOccurrence(testObjOne)); + assertEquals(2, testList.size()); + assertEquals(testObjThree, testList.peekLast()); + assertFalse(testList.removeLastOccurrence(testObjOne)); + } + + /** + * @tests {@link java.util.LinkedList#offerFirst(Object)} + */ + public void test_offerFirst() throws Exception { + assertTrue(testList.offerFirst(testObjOne)); + assertEquals(1, testList.size()); + assertEquals(testObjOne, testList.peek()); + assertTrue(testList.offerFirst(testObjOne)); + assertEquals(2, testList.size()); + assertEquals(testObjOne, testList.peek()); + assertTrue(testList.offerFirst(testObjTwo)); + assertEquals(3, testList.size()); + assertEquals(testObjTwo, testList.peek()); + assertEquals(testObjOne, testList.getLast()); + assertTrue(testList.offerFirst(null)); + assertEquals(4, testList.size()); + } + + /** + * @tests {@link java.util.LinkedList#offerLast(Object)} + */ + public void test_offerLast() throws Exception { + assertTrue(testList.offerLast(testObjOne)); + assertEquals(1, testList.size()); + assertEquals(testObjOne, testList.peek()); + assertTrue(testList.offerLast(testObjOne)); + assertEquals(2, testList.size()); + assertEquals(testObjOne, testList.peek()); + assertTrue(testList.offerLast(testObjTwo)); + assertEquals(3, testList.size()); + assertEquals(testObjOne, testList.peek()); + assertEquals(testObjTwo, testList.getLast()); + assertTrue(testList.offerLast(null)); + assertEquals(4, testList.size()); + } + + /** + * @tests {@link java.util.LinkedList#push(Object)} + */ + public void test_push() throws Exception { + testList.push(testObjOne); + assertEquals(1, testList.size()); + assertEquals(testObjOne, testList.peek()); + testList.push(testObjOne); + assertEquals(2, testList.size()); + assertEquals(testObjOne, testList.peek()); + testList.push(testObjTwo); + assertEquals(3, testList.size()); + assertEquals(testObjTwo, testList.peek()); + assertEquals(testObjOne, testList.getLast()); + testList.push(null); + assertEquals(4, testList.size()); + } + + /** + * @tests {@link java.util.LinkedList#pop()} + */ + public void test_pop() throws Exception { + assertTrue(testList.offerLast(testObjOne)); + assertTrue(testList.offerLast(testObjTwo)); + assertTrue(testList.offerLast(testObjThree)); + assertEquals(3, testList.size()); + assertEquals(testObjOne, testList.pop()); + assertEquals(2, testList.size()); + assertEquals(testObjTwo, testList.pop()); + assertEquals(testObjThree, testList.pop()); + assertEquals(0, testList.size()); + testList.push(null); + assertEquals(1, testList.size()); + assertNull(testList.pop()); + try { + testList.pop(); + fail("should throw NoSuchElementException "); + } catch (NoSuchElementException e) { + // expected + } + } + + /** + * @tests {@link java.util.LinkedList#descendingIterator()} + */ + public void test_descendingIterator() throws Exception { + assertFalse(testList.descendingIterator().hasNext()); + assertTrue(testList.add(testObjOne)); + assertTrue(testList.add(testObjTwo)); + assertTrue(testList.add(testObjOne)); + assertTrue(testList.add(testObjThree)); + assertTrue(testList.add(testObjLast)); + Iterator result = testList.descendingIterator(); + assertEquals(5, testList.size()); + try { + result.remove(); + fail("should throw IllegalStateException"); + } catch (IllegalStateException e) { + // expected + } + assertTrue(testList.add(testObjFour)); + + try { + assertEquals(testObjLast,result.next()); + fail("should throw ConcurrentModificationException"); + } catch (ConcurrentModificationException e) { + // expected + } + + result = testList.descendingIterator(); + assertEquals(testObjFour, result.next()); + assertEquals(testObjLast, result.next()); + assertEquals(testObjThree, result.next()); + assertEquals(testObjOne, result.next()); + assertEquals(testObjTwo, result.next()); + assertTrue(result.hasNext()); + result.remove(); + assertEquals(testObjOne, result.next()); + assertFalse(result.hasNext()); + try { + result.next(); + fail("should throw NoSuchElementException"); + } catch (NoSuchElementException e) { + // expected + } + } + /** + * @tests {@link java.util.LinkedList#pollFirst()} + */ + public void test_pollFirst() throws Exception { + assertTrue(testList.offerLast(testObjOne)); + assertTrue(testList.offerLast(testObjTwo)); + assertTrue(testList.offerLast(testObjThree)); + assertEquals(3, testList.size()); + assertEquals(testObjOne, testList.pollFirst()); + assertEquals(2, testList.size()); + assertEquals(testObjTwo, testList.pollFirst()); + assertEquals(testObjThree, testList.pollFirst()); + assertEquals(0, testList.size()); + assertNull(testList.pollFirst()); + } + + /** + * @tests {@link java.util.LinkedList#pollLast()} + */ + public void test_pollLast() throws Exception { + assertTrue(testList.offerLast(testObjOne)); + assertTrue(testList.offerLast(testObjTwo)); + assertTrue(testList.offerLast(testObjThree)); + assertEquals(3, testList.size()); + assertEquals(testObjThree, testList.pollLast()); + assertEquals(2, testList.size()); + assertEquals(testObjTwo, testList.pollLast()); + assertEquals(testObjOne, testList.pollLast()); + assertEquals(0, testList.size()); + assertNull(testList.pollFirst()); + } + + /** + * @tests {@link java.util.LinkedList#peekFirst()} + */ + public void test_peekFirst() throws Exception { + assertTrue(testList.offerLast(testObjOne)); + assertTrue(testList.offerLast(testObjTwo)); + assertTrue(testList.offerLast(testObjThree)); + assertEquals(3, testList.size()); + assertEquals(testObjOne, testList.peekFirst()); + assertEquals(3, testList.size()); + assertEquals(testObjOne, testList.pollFirst()); + assertEquals(testObjTwo, testList.peekFirst()); + assertEquals(testObjTwo, testList.pollFirst()); + assertEquals(testObjThree, testList.pollFirst()); + assertEquals(0, testList.size()); + assertEquals(null, testList.peekFirst()); + } + + /** + * @tests {@link java.util.LinkedList#peek()} + */ + public void test_peekLast() throws Exception { + assertTrue(testList.offerLast(testObjOne)); + assertTrue(testList.offerLast(testObjTwo)); + assertTrue(testList.offerLast(testObjThree)); + assertEquals(3, testList.size()); + assertEquals(testObjThree, testList.peekLast()); + assertEquals(3, testList.size()); + assertEquals(testObjThree, testList.pollLast()); + assertEquals(testObjTwo, testList.peekLast()); + assertEquals(testObjTwo, testList.pollLast()); + assertEquals(testObjOne, testList.pollLast()); + assertEquals(0, testList.size()); + assertNull(testList.peekLast()); + } + + + /** + * Sets up the fixture, for example, open a network connection. This method + * is called before a test is executed. + */ + protected void setUp() throws Exception { + super.setUp(); + ll = new LinkedList(); + for (int i = 0; i < objArray.length; i++) { + ll.add(objArray[i]); + } + testList = new LinkedList(); + testObjOne = new Object(); + testObjTwo = new Object(); + testObjThree = new Object(); + testObjFour = new Object(); + testObjLast = new Object(); + } +} diff --git a/src/test/java/harmony/Support_CollectionTest.java b/src/test/java/harmony/Support_CollectionTest.java new file mode 100644 index 000000000..8311b11ac --- /dev/null +++ b/src/test/java/harmony/Support_CollectionTest.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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. + */ + +package harmony; + +import java.util.Collection; +import java.util.TreeSet; + +/** + * @tests java.util.Collection + */ +public class Support_CollectionTest extends junit.framework.TestCase { + + Collection col; // must contain the Integers 0 to 99 + + public Support_CollectionTest(String p1) { + super(p1); + } + + public Support_CollectionTest(String p1, Collection c) { + super(p1); + col = c; + } + + + public void test(){ + } + + @Override + public void runTest() { + if(col==null) return; + + new Support_UnmodifiableCollectionTest("", col).runTest(); + + // setup + Collection myCollection = new TreeSet(); + myCollection.add(new Integer(101)); + myCollection.add(new Integer(102)); + myCollection.add(new Integer(103)); + + // add + assertTrue("CollectionTest - a) add did not work", col.add(new Integer( + 101))); + assertTrue("CollectionTest - b) add did not work", col + .contains(new Integer(101))); + + // remove + assertTrue("CollectionTest - a) remove did not work", col + .remove(new Integer(101))); + assertTrue("CollectionTest - b) remove did not work", !col + .contains(new Integer(101))); + + // addAll + assertTrue("CollectionTest - a) addAll failed", col + .addAll(myCollection)); + assertTrue("CollectionTest - b) addAll failed", col + .containsAll(myCollection)); + + // containsAll + assertTrue("CollectionTest - a) containsAll failed", col + .containsAll(myCollection)); + col.remove(new Integer(101)); + assertTrue("CollectionTest - b) containsAll failed", !col + .containsAll(myCollection)); + + // removeAll + assertTrue("CollectionTest - a) removeAll failed", col + .removeAll(myCollection)); + assertTrue("CollectionTest - b) removeAll failed", !col + .removeAll(myCollection)); // should not change the colletion + // the 2nd time around + assertTrue("CollectionTest - c) removeAll failed", !col + .contains(new Integer(102))); + assertTrue("CollectionTest - d) removeAll failed", !col + .contains(new Integer(103))); + + // retianAll + col.addAll(myCollection); + assertTrue("CollectionTest - a) retainAll failed", col + .retainAll(myCollection)); + assertTrue("CollectionTest - b) retainAll failed", !col + .retainAll(myCollection)); // should not change the colletion + // the 2nd time around + assertTrue("CollectionTest - c) retainAll failed", col + .containsAll(myCollection)); + assertTrue("CollectionTest - d) retainAll failed", !col + .contains(new Integer(0))); + assertTrue("CollectionTest - e) retainAll failed", !col + .contains(new Integer(50))); + + // clear + col.clear(); + assertTrue("CollectionTest - a) clear failed", col.isEmpty()); + assertTrue("CollectionTest - b) clear failed", !col + .contains(new Integer(101))); + + } + +} diff --git a/src/test/java/harmony/Support_ListTest.java b/src/test/java/harmony/Support_ListTest.java new file mode 100644 index 000000000..a3d9a8e0c --- /dev/null +++ b/src/test/java/harmony/Support_ListTest.java @@ -0,0 +1,225 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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. + */ + +package harmony; + +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; + +public class Support_ListTest extends junit.framework.TestCase { + + List list; // must contain the Integers 0 to 99 in order + + public Support_ListTest(String p1) { + super(p1); + } + + public Support_ListTest(String p1, List l) { + super(p1); + list = l; + } + + public void test(){ + } + + @Override + public void runTest() { + if(list==null) return; + + int hashCode = 1; + for (int counter = 0; counter < 100; counter++) { + Object elem; + elem = list.get(counter); + hashCode = 31 * hashCode + elem.hashCode(); + assertTrue("ListTest - get failed", elem + .equals(new Integer(counter))); + } + assertTrue("ListTest - hashCode failed", hashCode == list.hashCode()); + + list.add(50, new Integer(1000)); + assertTrue("ListTest - a) add with index failed--did not insert", list + .get(50).equals(new Integer(1000))); + assertTrue( + "ListTest - b) add with index failed--did not move following elements", + list.get(51).equals(new Integer(50))); + assertTrue( + "ListTest - c) add with index failed--affected previous elements", + list.get(49).equals(new Integer(49))); + + list.set(50, new Integer(2000)); + assertTrue("ListTest - a) set failed--did not set", list.get(50) + .equals(new Integer(2000))); + assertTrue("ListTest - b) set failed--affected following elements", + list.get(51).equals(new Integer(50))); + assertTrue("ListTest - c) set failed--affected previous elements", list + .get(49).equals(new Integer(49))); + + list.remove(50); + assertTrue("ListTest - a) remove with index failed--did not remove", + list.get(50).equals(new Integer(50))); + assertTrue( + "ListTest - b) remove with index failed--did not move following elements", + list.get(51).equals(new Integer(51))); + assertTrue( + "ListTest - c) remove with index failed--affected previous elements", + list.get(49).equals(new Integer(49))); + + List myList = new LinkedList(); + myList.add(new Integer(500)); + myList.add(new Integer(501)); + myList.add(new Integer(502)); + + list.addAll(50, myList); + assertTrue("ListTest - a) addAll with index failed--did not insert", + list.get(50).equals(new Integer(500))); + assertTrue("ListTest - b) addAll with index failed--did not insert", + list.get(51).equals(new Integer(501))); + assertTrue("ListTest - c) addAll with index failed--did not insert", + list.get(52).equals(new Integer(502))); + assertTrue( + "ListTest - d) addAll with index failed--did not move following elements", + list.get(53).equals(new Integer(50))); + assertTrue( + "ListTest - e) addAll with index failed--affected previous elements", + list.get(49).equals(new Integer(49))); + + List mySubList = list.subList(50, 53); + assertEquals(3, mySubList.size()); + assertTrue( + "ListTest - a) sublist Failed--does not contain correct elements", + mySubList.get(0).equals(new Integer(500))); + assertTrue( + "ListTest - b) sublist Failed--does not contain correct elements", + mySubList.get(1).equals(new Integer(501))); + assertTrue( + "ListTest - c) sublist Failed--does not contain correct elements", + mySubList.get(2).equals(new Integer(502))); + + t_listIterator(mySubList); + + mySubList.clear(); + assertEquals("ListTest - Clearing the sublist did not remove the appropriate elements from the original list", + 100, list.size()); + + t_listIterator(list); + ListIterator li = list.listIterator(); + for (int counter = 0; li.hasNext(); counter++) { + Object elem; + elem = li.next(); + assertTrue("ListTest - listIterator failed", elem + .equals(new Integer(counter))); + } + + new Support_CollectionTest("", list).runTest(); + + } + + public void t_listIterator(List list) { + ListIterator li = list.listIterator(1); + assertEquals("listIterator(1)", li.next() , list.get(1)); + + int orgSize = list.size(); + li = list.listIterator(); + for (int i = 0; i <= orgSize; i++) { + if (i == 0) { + assertTrue("list iterator hasPrevious(): " + i, !li + .hasPrevious()); + } else { + assertTrue("list iterator hasPrevious(): " + i, li + .hasPrevious()); + } + if (i == list.size()) { + assertTrue("list iterator hasNext(): " + i, !li.hasNext()); + } else { + assertTrue("list iterator hasNext(): " + i, li.hasNext()); + } + assertTrue("list iterator nextIndex(): " + i, li.nextIndex() == i); + assertTrue("list iterator previousIndex(): " + i, li + .previousIndex() == i - 1); + boolean exception = false; + try { + assertEquals("list iterator next(): " + i, li.next() , list + .get(i)); + } catch (NoSuchElementException e) { + exception = true; + } + if (i == list.size()) { + assertTrue("list iterator next() exception: " + i, exception); + } else { + assertTrue("list iterator next() exception: " + i, !exception); + } + } + + for (int i = orgSize - 1; i >= 0; i--) { + assertEquals("list iterator previous(): " + i, li.previous() , list + .get(i)); + assertTrue("list iterator nextIndex()2: " + i, li.nextIndex() == i); + assertTrue("list iterator previousIndex()2: " + i, li + .previousIndex() == i - 1); + if (i == 0) { + assertTrue("list iterator hasPrevious()2: " + i, !li + .hasPrevious()); + } else { + assertTrue("list iterator hasPrevious()2: " + i, li + .hasPrevious()); + } + assertTrue("list iterator hasNext()2: " + i, li.hasNext()); + } + boolean exception = false; + try { + li.previous(); + } catch (NoSuchElementException e) { + exception = true; + } + assertTrue("list iterator previous() exception", exception); + + Integer add1 = new Integer(600); + Integer add2 = new Integer(601); + li.add(add1); + assertTrue("list iterator add(), size()", list.size() == (orgSize + 1)); + assertEquals("list iterator add(), nextIndex()", 1, li.nextIndex()); + assertEquals("list iterator add(), previousIndex()", + 0, li.previousIndex()); + Object next = li.next(); + assertEquals("list iterator add(), next(): " + next, next , list.get(1)); + li.add(add2); + Object previous = li.previous(); + assertEquals("list iterator add(), previous(): " + previous, + previous , add2); + assertEquals("list iterator add(), nextIndex()2", 2, li.nextIndex()); + assertEquals("list iterator add(), previousIndex()2", + 1, li.previousIndex()); + + li.remove(); + assertTrue("list iterator remove(), size()", + list.size() == (orgSize + 1)); + assertEquals("list iterator remove(), nextIndex()", 2, li.nextIndex()); + assertEquals("list iterator remove(), previousIndex()", 1, li + .previousIndex()); + assertEquals("list iterator previous()2", li.previous() , list.get(1)); + assertEquals("list iterator previous()3", li.previous() , list.get(0)); + assertEquals("list iterator next()2", li.next() , list.get(0)); + li.remove(); + assertTrue("list iterator hasPrevious()3", !li.hasPrevious()); + assertTrue("list iterator hasNext()3", li.hasNext()); + assertTrue("list iterator size()", list.size() == orgSize); + assertEquals("list iterator nextIndex()3", 0, li.nextIndex()); + assertEquals("list iterator previousIndex()3", -1, li.previousIndex()); + } +} diff --git a/src/test/java/harmony/Support_UnmodifiableCollectionTest.java b/src/test/java/harmony/Support_UnmodifiableCollectionTest.java new file mode 100644 index 000000000..b5c75fd7f --- /dev/null +++ b/src/test/java/harmony/Support_UnmodifiableCollectionTest.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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. + */ + +package harmony; + +import junit.framework.TestCase; + +import java.util.*; + +public class Support_UnmodifiableCollectionTest extends TestCase { + + Collection col; + + // must be a collection containing the Integers 0 to 99 (which will iterate + // in order) + + public Support_UnmodifiableCollectionTest(String p1) { + super(p1); + } + + public Support_UnmodifiableCollectionTest(String p1, Collection c) { + super(p1); + col = c; + } + + + public void test(){ + } + + @Override + public void runTest() { + if(col==null) return; + + // contains + assertTrue("UnmodifiableCollectionTest - should contain 0", col + .contains(new Integer(0))); + assertTrue("UnmodifiableCollectionTest - should contain 50", col + .contains(new Integer(50))); + assertTrue("UnmodifiableCollectionTest - should not contain 100", !col + .contains(new Integer(100))); + + // containsAll + HashSet hs = new HashSet(); + hs.add(new Integer(0)); + hs.add(new Integer(25)); + hs.add(new Integer(99)); + assertTrue( + "UnmodifiableCollectionTest - should contain set of 0, 25, and 99", + col.containsAll(hs)); + hs.add(new Integer(100)); + assertTrue( + "UnmodifiableCollectionTest - should not contain set of 0, 25, 99 and 100", + !col.containsAll(hs)); + + // isEmpty + assertTrue("UnmodifiableCollectionTest - should not be empty", !col + .isEmpty()); + + // iterator + Iterator it = col.iterator(); + SortedSet ss = new TreeSet(); + while (it.hasNext()) { + ss.add(it.next()); + } + it = ss.iterator(); + for (int counter = 0; it.hasNext(); counter++) { + int nextValue = it.next().intValue(); + assertTrue( + "UnmodifiableCollectionTest - Iterator returned wrong value. Wanted: " + + counter + " got: " + nextValue, + nextValue == counter); + } + + // size + assertTrue( + "UnmodifiableCollectionTest - returned wrong size. Wanted 100, got: " + + col.size(), col.size() == 100); + + // toArray + Object[] objArray; + objArray = col.toArray(); + for (int counter = 0; it.hasNext(); counter++) { + assertTrue( + "UnmodifiableCollectionTest - toArray returned incorrect array", + objArray[counter] == it.next()); + } + + // toArray (Object[]) + objArray = new Object[100]; + col.toArray(objArray); + for (int counter = 0; it.hasNext(); counter++) { + assertTrue( + "UnmodifiableCollectionTest - toArray(Object) filled array incorrectly", + objArray[counter] == it.next()); + } + + } + +} diff --git a/src/test/java/org/mapdb/AsyncWriteEngineTest.java b/src/test/java/org/mapdb/AsyncWriteEngineTest.java deleted file mode 100644 index a18555afc..000000000 --- a/src/test/java/org/mapdb/AsyncWriteEngineTest.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicLong; - -import static org.junit.Assert.*; - -/** -* @author Jan Kotek -*/ -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class AsyncWriteEngineTest{ - - File index = UtilsTest.tempDbFile(); - AsyncWriteEngine engine; - - @Before public void reopenStore() throws IOException { - assertNotNull(index); - if(engine !=null) - engine.close(); - engine = new AsyncWriteEngine( - DBMaker.newFileDB(index).transactionDisable().cacheDisable().makeEngine() - ); - } - - @After - public void close(){ - engine.close(); - } - - - @Test(timeout = 1000000) - public void write_fetch_update_delete() throws IOException { - long recid = engine.put("aaa", Serializer.STRING_NOSIZE); - assertEquals("aaa", engine.get(recid, Serializer.STRING_NOSIZE)); - reopenStore(); - assertEquals("aaa", engine.get(recid, Serializer.STRING_NOSIZE)); - engine.update(recid, "bbb", Serializer.STRING_NOSIZE); - assertEquals("bbb", engine.get(recid, Serializer.STRING_NOSIZE)); - reopenStore(); - assertEquals("bbb", engine.get(recid, Serializer.STRING_NOSIZE)); - - } - - - @Test(timeout = 0xFFFF) - public void concurrent_updates_test() throws InterruptedException, IOException { - final int threadNum = 16; - final int updates = 1000; - final CountDownLatch latch = new CountDownLatch(threadNum); - final Map recids = new ConcurrentHashMap(); - - for(int i = 0;i long put(A value, Serializer serializer) { - putCounter.incrementAndGet(); - return super.put(value, serializer); - } - - @Override - public void update(long recid, A value, Serializer serializer) { - putCounter.incrementAndGet(); - super.update(recid, value, serializer); - } - - }; - AsyncWriteEngine a = new AsyncWriteEngine(t); - byte[] b = new byte[124]; - - long max = 100; - - ArrayList l = new ArrayList(); - for(int i=0;i list = new ArrayList (); - for(long i = 0; i<1000;i++){ - String s = ""+ Math.random()+(i*i*i); - m.put(s,s+"aa"); - } - - for(String s:list){ - assertEquals(s+"aa",m.get(s)); - } - } - - - @Test public void testUUID() throws IOException { - List ids = new ArrayList(); - for(int i=0;i<100;i++) - ids.add(java.util.UUID.randomUUID()); - - long[] vv = (long[]) UUID.arrayToKeys(ids.toArray()); - - int i=0; - for(java.util.UUID u:ids){ - assertEquals(u.getMostSignificantBits(),vv[i++]); - assertEquals(u.getLeastSignificantBits(),vv[i++]); - } - - //clone - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - UUID.serialize(out, vv); - - DataInput in = new DataIO.DataInputByteArray(out.copyBytes()); - long[] nn = (long[]) UUID.deserialize(in, ids.size()); - - assertArrayEquals(vv, nn); - - //test key addition - java.util.UUID r = java.util.UUID.randomUUID(); - ids.add(10,r); - long[] vv2 = (long[]) UUID.putKey(vv,10,r); - i=0; - for(java.util.UUID u:ids){ - assertEquals(u.getMostSignificantBits(),vv2[i++]); - assertEquals(u.getLeastSignificantBits(),vv2[i++]); - } - - vv2 = (long[]) UUID.deleteKey(vv2,10); - - assertArrayEquals(vv,vv2); - } - - void randomSerializer(BTreeKeySerializer ser, Fun.Function0 fab){ - Set keys2 = new TreeSet(ser.comparator()); - - for(int i=0;i<3;i++){ - keys2.add(fab.run()); - } - Object keys = ser.arrayToKeys(keys2.toArray()); - - for(int i=0;i<1e3;i++){ - Object key = fab.run(); - long[] child = new long[keys2.size()]; - for(int ii=0;ii map; - - - @Override - protected void setUp() throws Exception { - r = DBMaker.newMemoryDB().transactionDisable().cacheDisable().makeEngine(); - map = new BTreeMap(r, createRootRef(r,BASIC, Serializer.BASIC,0), - 6, valsOutsideNodes, 0, BASIC, valueSerializer, 0); - } - - - @After - public void close(){ - r.close(); - } - - /** - * When valsOutsideNodes is true should not deserialize value during .containsKey - */ - public void testContainsKeySkipsValueDeserialisation() { - - map.put(1, "abc"); - - boolean contains = map.containsKey(1); - - assertEquals(true, contains ); - assertEquals("Deserialize was called", !valsOutsideNodes, valueSerializer.isDeserializeCalled() ); - } - - static class RecordingSerializer extends SerializerBase implements Serializable { - - private static final long serialVersionUID = 1L; - private boolean deserializeCalled = false; - - @Override - public Object deserialize(DataInput is, int capacity) throws IOException { - deserializeCalled = true; - return super.deserialize(is, capacity); - } - - public boolean isDeserializeCalled() { - return deserializeCalled; - } - } -} diff --git a/src/test/java/org/mapdb/BTreeMapExtendTest.java b/src/test/java/org/mapdb/BTreeMapExtendTest.java deleted file mode 100644 index 2c5de74b4..000000000 --- a/src/test/java/org/mapdb/BTreeMapExtendTest.java +++ /dev/null @@ -1,7780 +0,0 @@ -package org.mapdb; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 - * - * http://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. - */ - -import junit.framework.TestCase; - -import java.util.*; -import java.util.Map.Entry; - - - -public class BTreeMapExtendTest extends TestCase { - - BTreeMap tm; - - BTreeMap tm_comparator; - - SortedMap subMap_default; - - SortedMap subMap_startExcluded_endExcluded; - - SortedMap subMap_startExcluded_endIncluded; - - SortedMap subMap_startIncluded_endExcluded; - - SortedMap subMap_startIncluded_endIncluded; - - SortedMap subMap_default_beforeStart_100; - - SortedMap subMap_default_afterEnd_109; - - NavigableMap navigableMap_startExcluded_endExcluded; - - NavigableMap navigableMap_startExcluded_endIncluded; - - NavigableMap navigableMap_startIncluded_endExcluded; - - NavigableMap navigableMap_startIncluded_endIncluded; - - SortedMap subMap_default_comparator; - - SortedMap subMap_startExcluded_endExcluded_comparator; - - SortedMap subMap_startExcluded_endIncluded_comparator; - - SortedMap subMap_startIncluded_endExcluded_comparator; - - SortedMap subMap_startIncluded_endIncluded_comparator; - - Object objArray[] = new Object[1000]; - - protected BTreeMap newBTreeMap() { - return DBMaker.newMemoryDB().cacheDisable().transactionDisable().make().getTreeMap("Test"); - } - - - public static class Outside extends BTreeMapExtendTest{ - @Override protected BTreeMap newBTreeMap() { - return DBMaker.newMemoryDB().cacheDisable().transactionDisable().make() - .createTreeMap("Test").valuesOutsideNodesEnable().make(); - } - - } - - - public void test_TreeMap_Constructor_Default() { - BTreeMap treeMap = newBTreeMap(); - assertTrue(treeMap.isEmpty()); - assertNotNull(treeMap.comparator()); - assertEquals(0, treeMap.size()); - - try { - treeMap.firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - assertNull(treeMap.firstEntry()); - - try { - treeMap.lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - assertNull(treeMap.lastEntry()); - - try { - treeMap.ceilingKey(1); - } catch (NoSuchElementException e) { - // Expected - } - assertNull(treeMap.ceilingEntry(1)); - - try { - treeMap.floorKey(1); - } catch (NoSuchElementException e) { - // Expected - } - assertNull(treeMap.floorEntry(1)); - assertNull(treeMap.lowerKey(1)); - assertNull(treeMap.lowerEntry(1)); - assertNull(treeMap.higherKey(1)); - assertNull(treeMap.higherEntry(1)); - assertFalse(treeMap.containsKey(1)); - assertFalse(treeMap.containsValue(1)); - assertNull(treeMap.get(1)); - - assertNull(treeMap.pollFirstEntry()); - assertNull(treeMap.pollLastEntry()); - assertEquals(0, treeMap.values().size()); - } - - - - - public void test_TreeMap_clear() { - tm.clear(); - assertEquals(0, tm.size()); - } - - - public void test_SubMap_Constructor() { - } - - public void test_SubMap_clear() { - subMap_default.clear(); - assertEquals(0, subMap_default.size()); - } - - public void test_SubMap_comparator() { - assertEquals(tm.comparator(), subMap_default.comparator()); - } - - public void test_SubMap_containsKey() { - String key = null; - for (int counter = 101; counter < 109; counter++) { - key = objArray[counter].toString(); - assertTrue("SubMap contains incorrect elements", subMap_default - .containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsKey(key)); - } - - // Check boundary - key = objArray[100].toString(); - assertTrue("SubMap contains incorrect elements", subMap_default - .containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsKey(key)); - - key = objArray[109].toString(); - assertFalse("SubMap contains incorrect elements", subMap_default - .containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsKey(key)); - - // With Comparator - for (int counter = 101; counter < 109; counter++) { - key = objArray[counter].toString(); - assertTrue("SubMap contains incorrect elements", - subMap_default_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded_comparator - .containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded_comparator - .containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded_comparator - .containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded_comparator - .containsKey(key)); - } - - // Check boundary - key = objArray[100].toString(); - assertTrue("SubMap contains incorrect elements", - subMap_default_comparator.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded_comparator.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded_comparator.containsKey(key)); - - key = objArray[109].toString(); - assertFalse("SubMap contains incorrect elements", - subMap_default_comparator.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded_comparator.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded_comparator.containsKey(key)); - } - - public void test_SubMap_containsValue() { - Object value = null; - for (int counter = 101; counter < 109; counter++) { - value = objArray[counter]; - assertTrue("SubMap contains incorrect elements", subMap_default - .containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsValue(value)); - } - - // Check boundary - value = objArray[100]; - assertTrue("SubMap contains incorrect elements", subMap_default - .containsValue(value)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsValue(value)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsValue(value)); - - value = objArray[109]; - assertFalse("SubMap contains incorrect elements", subMap_default - .containsValue(value)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsValue(value)); - assertFalse("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsValue(value)); - -// assertFalse(subMap_default.containsValue(null)); - - } - - public void test_SubMap_entrySet() { - Set entrySet = subMap_default.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(9, entrySet.size()); - - entrySet = subMap_startExcluded_endExcluded.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(8, entrySet.size()); - - entrySet = subMap_startExcluded_endIncluded.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(9, entrySet.size()); - - entrySet = subMap_startIncluded_endExcluded.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(9, entrySet.size()); - - entrySet = subMap_startIncluded_endIncluded.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(10, entrySet.size()); - } - - public void test_SubMap_firstKey() { - String firstKey1 = new Integer(100).toString(); - String firstKey2 = new Integer(101).toString(); - assertEquals(firstKey1, subMap_default.firstKey()); - assertEquals(firstKey2, subMap_startExcluded_endExcluded.firstKey()); - assertEquals(firstKey2, subMap_startExcluded_endIncluded.firstKey()); - assertEquals(firstKey1, subMap_startIncluded_endExcluded.firstKey()); - assertEquals(firstKey1, subMap_startIncluded_endIncluded.firstKey()); - - try { - subMap_default.subMap(firstKey1, firstKey1).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.subMap(firstKey2, firstKey2) - .firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.subMap(firstKey2, firstKey2) - .firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.subMap(firstKey1, firstKey1) - .firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.subMap(firstKey1, firstKey1) - .firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - // With Comparator - assertEquals(firstKey1, subMap_default_comparator.firstKey()); - assertEquals(firstKey2, subMap_startExcluded_endExcluded_comparator - .firstKey()); - assertEquals(firstKey2, subMap_startExcluded_endIncluded_comparator - .firstKey()); - assertEquals(firstKey1, subMap_startIncluded_endExcluded_comparator - .firstKey()); - assertEquals(firstKey1, subMap_startIncluded_endIncluded_comparator - .firstKey()); - - try { - subMap_default_comparator.subMap(firstKey1, firstKey1).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator.subMap(firstKey2, - firstKey2).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator.subMap(firstKey2, - firstKey2).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator.subMap(firstKey1, - firstKey1).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator.subMap(firstKey1, - firstKey1).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - } - - public void test_SubMap_lastKey() { - String lastKey1 = new Integer(108).toString(); - String lastKey2 = new Integer(109).toString(); - assertEquals(lastKey1, subMap_default.lastKey()); - assertEquals(lastKey1, subMap_startExcluded_endExcluded.lastKey()); - assertEquals(lastKey2, subMap_startExcluded_endIncluded.lastKey()); - assertEquals(lastKey1, subMap_startIncluded_endExcluded.lastKey()); - assertEquals(lastKey2, subMap_startIncluded_endIncluded.lastKey()); - - try { - subMap_default.subMap(lastKey1, lastKey1).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.subMap(lastKey1, lastKey1) - .lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.subMap(lastKey2, lastKey2) - .lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.subMap(lastKey1, lastKey1) - .lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.subMap(lastKey2, lastKey2) - .lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - // With Comparator - assertEquals(lastKey1, subMap_default_comparator.lastKey()); - assertEquals(lastKey1, subMap_startExcluded_endExcluded_comparator - .lastKey()); - assertEquals(lastKey2, subMap_startExcluded_endIncluded_comparator - .lastKey()); - assertEquals(lastKey1, subMap_startIncluded_endExcluded_comparator - .lastKey()); - assertEquals(lastKey2, subMap_startIncluded_endIncluded_comparator - .lastKey()); - - try { - subMap_default_comparator.subMap(lastKey1, lastKey1).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator.subMap(lastKey1, - lastKey1).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator.subMap(lastKey2, - lastKey2).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator.subMap(lastKey1, - lastKey1).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator.subMap(lastKey2, - lastKey2).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - public void test_SubMap_get() { - // left boundary - Integer value = new Integer(100); - assertEquals(value, subMap_default.get(value.toString())); - assertEquals(null, subMap_startExcluded_endExcluded.get(value - .toString())); - assertEquals(null, subMap_startExcluded_endIncluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endIncluded.get(value - .toString())); - - // normal value - value = new Integer(105); - assertEquals(value, subMap_default.get(value.toString())); - assertEquals(value, subMap_startExcluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startExcluded_endIncluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endIncluded.get(value - .toString())); - - // right boundary - value = new Integer(109); - assertEquals(null, subMap_default.get(value.toString())); - assertEquals(null, subMap_startExcluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startExcluded_endIncluded.get(value - .toString())); - assertEquals(null, subMap_startIncluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endIncluded.get(value - .toString())); - - // With Comparator to test inInRange - // left boundary - value = new Integer(100); - assertEquals(value, subMap_default_comparator.get(value.toString())); - - // normal value - value = new Integer(105); - assertEquals(value, subMap_default_comparator.get(value.toString())); - - // right boundary - value = new Integer(109); - assertEquals(null, subMap_default_comparator.get(value.toString())); - } - - public void test_SubMap_headMap() { - String endKey = new Integer(99).toString(); - try { - subMap_default.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - SortedMap headMap = null; - endKey = new Integer(100).toString(); - headMap = subMap_default.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startExcluded_endExcluded.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startExcluded_endIncluded.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startIncluded_endExcluded.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startIncluded_endIncluded.headMap(endKey); - assertEquals(0, headMap.size()); - - for (int i = 0, j = 101; i < 8; i++) { - endKey = new Integer(i + j).toString(); - headMap = subMap_default.headMap(endKey); - assertEquals(i + 1, headMap.size()); - - headMap = subMap_startExcluded_endExcluded.headMap(endKey); - assertEquals(i, headMap.size()); - - headMap = subMap_startExcluded_endIncluded.headMap(endKey); - assertEquals(i, headMap.size()); - - headMap = subMap_startIncluded_endExcluded.headMap(endKey); - assertEquals(i + 1, headMap.size()); - - headMap = subMap_startIncluded_endIncluded.headMap(endKey); - assertEquals(i + 1, headMap.size()); - } - - endKey = new Integer(109).toString(); - headMap = subMap_default.headMap(endKey); - assertEquals(9, headMap.size()); - - headMap = subMap_startExcluded_endExcluded.headMap(endKey); - assertEquals(8, headMap.size()); - - headMap = subMap_startExcluded_endIncluded.headMap(endKey); - assertEquals(8, headMap.size()); - - headMap = subMap_startIncluded_endExcluded.headMap(endKey); - assertEquals(9, headMap.size()); - - headMap = subMap_startIncluded_endIncluded.headMap(endKey); - assertEquals(9, headMap.size()); - - endKey = new Integer(110).toString(); - try { - subMap_default.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // With Comparator - endKey = new Integer(99).toString(); - try { - subMap_default_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - headMap = null; - endKey = new Integer(100).toString(); - headMap = subMap_default_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startExcluded_endExcluded_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startExcluded_endIncluded_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startIncluded_endExcluded_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startIncluded_endIncluded_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - for (int i = 0, j = 101; i < 8; i++) { - endKey = new Integer(i + j).toString(); - headMap = subMap_default_comparator.headMap(endKey); - assertEquals(i + 1, headMap.size()); - - headMap = subMap_startExcluded_endExcluded_comparator - .headMap(endKey); - assertEquals(i, headMap.size()); - - headMap = subMap_startExcluded_endIncluded_comparator - .headMap(endKey); - assertEquals(i, headMap.size()); - - headMap = subMap_startIncluded_endExcluded_comparator - .headMap(endKey); - assertEquals(i + 1, headMap.size()); - - headMap = subMap_startIncluded_endIncluded_comparator - .headMap(endKey); - assertEquals(i + 1, headMap.size()); - } - - endKey = new Integer(108).toString(); - headMap = subMap_default_comparator.headMap(endKey); - assertEquals(8, headMap.size()); - - headMap = subMap_startExcluded_endExcluded_comparator.headMap(endKey); - assertEquals(7, headMap.size()); - - headMap = subMap_startExcluded_endIncluded_comparator.headMap(endKey); - assertEquals(7, headMap.size()); - - headMap = subMap_startIncluded_endExcluded_comparator.headMap(endKey); - assertEquals(8, headMap.size()); - - headMap = subMap_startIncluded_endIncluded_comparator.headMap(endKey); - assertEquals(8, headMap.size()); - - endKey = new Integer(110).toString(); - try { - subMap_default_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } - - public void test_SubMap_isEmpty() { - assertFalse(subMap_default.isEmpty()); - assertFalse(subMap_startExcluded_endExcluded.isEmpty()); - assertFalse(subMap_startExcluded_endIncluded.isEmpty()); - assertFalse(subMap_startIncluded_endExcluded.isEmpty()); - assertFalse(subMap_startIncluded_endIncluded.isEmpty()); - - Object startKey = new Integer(100); - Object endKey = startKey; - SortedMap subMap = tm.subMap(startKey.toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - subMap = subMap_default.subMap(startKey.toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - subMap = subMap_startIncluded_endExcluded.subMap(startKey.toString(), - endKey.toString()); - assertTrue(subMap.isEmpty()); - subMap = subMap_startIncluded_endIncluded.subMap(startKey.toString(), - endKey.toString()); - assertTrue(subMap.isEmpty()); - - for (int i = 0, j = 101; i < 8; i++) { - startKey = i + j; - endKey = startKey; - - subMap = subMap_default.subMap(startKey.toString(), endKey - .toString()); - assertTrue(subMap.isEmpty()); - - subMap = subMap_startExcluded_endExcluded.subMap(startKey - .toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - - subMap = subMap_startExcluded_endIncluded.subMap(startKey - .toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - - subMap = subMap_startIncluded_endExcluded.subMap(startKey - .toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - - subMap = subMap_startIncluded_endIncluded.subMap(startKey - .toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - } - - for (int i = 0, j = 101; i < 5; i++) { - startKey = i + j; - endKey = i + j + 4; - - subMap = subMap_default.subMap(startKey.toString(), endKey - .toString()); - assertFalse(subMap.isEmpty()); - - subMap = subMap_startExcluded_endExcluded.subMap(startKey - .toString(), endKey.toString()); - assertFalse(subMap.isEmpty()); - - subMap = subMap_startExcluded_endIncluded.subMap(startKey - .toString(), endKey.toString()); - assertFalse(subMap.isEmpty()); - - subMap = subMap_startIncluded_endExcluded.subMap(startKey - .toString(), endKey.toString()); - assertFalse(subMap.isEmpty()); - - subMap = subMap_startIncluded_endIncluded.subMap(startKey - .toString(), endKey.toString()); - assertFalse(subMap.isEmpty()); - } - - startKey = new Integer(109).toString(); - endKey = startKey; - subMap = tm.subMap(startKey.toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - subMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey); - assertTrue(subMap.isEmpty()); - subMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey); - assertTrue(subMap.isEmpty()); - - } - - public void test_SubMap_keySet() { - Set keySet = subMap_default.keySet(); - assertFalse(keySet.isEmpty()); - assertEquals(9, keySet.size()); - - keySet = subMap_startExcluded_endExcluded.entrySet(); - assertFalse(keySet.isEmpty()); - assertEquals(8, keySet.size()); - - keySet = subMap_startExcluded_endIncluded.entrySet(); - assertFalse(keySet.isEmpty()); - assertEquals(9, keySet.size()); - - keySet = subMap_startIncluded_endExcluded.entrySet(); - assertFalse(keySet.isEmpty()); - assertEquals(9, keySet.size()); - - keySet = subMap_startIncluded_endIncluded.entrySet(); - assertFalse(keySet.isEmpty()); - assertEquals(10, keySet.size()); - } - - public void test_SubMap_put() { - Integer value = new Integer(100); - int addValue = 5; - - subMap_default.put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_default.get(value.toString())); - - try { - subMap_startExcluded_endExcluded.put(value.toString(), value - + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.put(value.toString(), value - + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subMap_startIncluded_endExcluded - .put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_startIncluded_endExcluded - .get(value.toString())); - - subMap_startIncluded_endIncluded - .put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_startIncluded_endIncluded - .get(value.toString())); - - value = new Integer(109); - try { - subMap_default.put(value.toString(), value + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.put(value.toString(), value - + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subMap_startExcluded_endIncluded - .put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_startExcluded_endIncluded - .get(value.toString())); - - try { - subMap_startIncluded_endExcluded.put(value.toString(), value - + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subMap_startIncluded_endIncluded - .put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_startIncluded_endIncluded - .get(value.toString())); - } - - public void test_SubMap_remove() { - Integer value = new Integer(100); - - subMap_default.remove(value.toString()); - assertNull(subMap_default.get(value.toString())); - - subMap_startExcluded_endExcluded.remove(value.toString()); - assertNull(subMap_startExcluded_endExcluded.get(value.toString())); - - subMap_startExcluded_endIncluded.remove(value.toString()); - assertNull(subMap_startExcluded_endIncluded.get(value.toString())); - - subMap_startIncluded_endExcluded.remove(value.toString()); - assertNull(subMap_startIncluded_endExcluded.get(value.toString())); - - subMap_startIncluded_endIncluded.remove(value.toString()); - assertNull(subMap_startIncluded_endIncluded.get(value.toString())); - - value = new Integer(109); - subMap_default.remove(value.toString()); - assertNull(subMap_default.get(value.toString())); - - subMap_startExcluded_endExcluded.remove(value.toString()); - assertNull(subMap_startExcluded_endExcluded.get(value.toString())); - - subMap_startExcluded_endIncluded.remove(value.toString()); - assertNull(subMap_startExcluded_endIncluded.get(value.toString())); - - subMap_startIncluded_endExcluded.remove(value.toString()); - assertNull(subMap_startIncluded_endExcluded.get(value.toString())); - - subMap_startIncluded_endIncluded.remove(value.toString()); - assertNull(subMap_startIncluded_endIncluded.get(value.toString())); - } - - public void test_SubMap_subMap_NoComparator() { - String startKey = new Integer[100].toString(); - String endKey = new Integer[100].toString(); - try { - subMap_default.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - SortedMap subSubMap = null; - for (int i = 101; i < 109; i++) { - startKey = new Integer(i).toString(); - endKey = startKey; - - subSubMap = subMap_default.subMap(startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded.subMap(startKey, - endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, - endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded.subMap(startKey, - endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, - endKey); - assertEquals(0, subSubMap.size()); - } - - for (int i = 101, j = 5; i < 105; i++) { - startKey = new Integer(i).toString(); - endKey = new Integer(i + j).toString(); - - subSubMap = subMap_default.subMap(startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded.subMap(startKey, - endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, - endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded.subMap(startKey, - endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, - endKey); - assertEquals(j, subSubMap.size()); - } - - startKey = new Integer(108).toString(); - endKey = new Integer(109).toString(); - - subSubMap = subMap_default.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - startKey = new Integer(109).toString(); - endKey = new Integer(109).toString(); - -// try { -// subMap_default.subMap(startKey, endKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } -// -// try { -// subMap_startExcluded_endExcluded.subMap(startKey, endKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey); - assertEquals(0, subSubMap.size()); - -// try { -// subMap_startIncluded_endExcluded.subMap(startKey, endKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey); - assertEquals(0, subSubMap.size()); - } - - public void test_SubMap_subMap_Comparator() { - String startKey = new Integer[100].toString(); - String endKey = new Integer[100].toString(); - try { - subMap_default_comparator.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - SortedMap subSubMap = null; - for (int i = 101; i < 109; i++) { - startKey = new Integer(i).toString(); - endKey = startKey; - - subSubMap = subMap_default_comparator.subMap(startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - } - - for (int i = 101, j = 5; i < 105; i++) { - startKey = new Integer(i).toString(); - endKey = new Integer(i + j).toString(); - - subSubMap = subMap_default_comparator.subMap(startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(j, subSubMap.size()); - } - - startKey = new Integer(108).toString(); - endKey = new Integer(109).toString(); - - subSubMap = subMap_default_comparator.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(1, subSubMap.size()); - - startKey = new Integer(109).toString(); - endKey = new Integer(109).toString(); -// -// try { -// subMap_default_comparator.subMap(startKey, endKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - -// try { -// subMap_startExcluded_endExcluded_comparator -// .subMap(startKey, endKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - subSubMap = subMap_startExcluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - -// try { -// subMap_startIncluded_endExcluded_comparator -// .subMap(startKey, endKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - subSubMap = subMap_startIncluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - } - - public void test_SubMap_tailMap() { - String startKey = new Integer(99).toString(); - try { - subMap_default.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - SortedMap tailMap = null; - - startKey = new Integer(100).toString(); - tailMap = subMap_default.tailMap(startKey); - assertEquals(9, tailMap.size()); - - try { - subMap_startExcluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - tailMap = subMap_startIncluded_endExcluded.tailMap(startKey); - assertEquals(9, tailMap.size()); - - tailMap = subMap_startIncluded_endIncluded.tailMap(startKey); - assertEquals(10, tailMap.size()); - - for (int i = 0, j = 101, end = 8; i < end; i++) { - startKey = new Integer(i + j).toString(); - tailMap = subMap_default.tailMap(startKey); - assertEquals(end - i, tailMap.size()); - - tailMap = subMap_startExcluded_endExcluded.tailMap(startKey); - assertEquals(end - i, tailMap.size()); - - tailMap = subMap_startExcluded_endIncluded.tailMap(startKey); - assertEquals(end - i + 1, tailMap.size()); - - tailMap = subMap_startIncluded_endExcluded.tailMap(startKey); - assertEquals(end - i, tailMap.size()); - - tailMap = subMap_startIncluded_endIncluded.tailMap(startKey); - assertEquals(end - i + 1, tailMap.size()); - } - - startKey = new Integer(109).toString(); -// try { -// subMap_default.tailMap(startKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } -// try { -// subMap_startExcluded_endExcluded.tailMap(startKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - tailMap = subMap_startExcluded_endIncluded.tailMap(startKey); - assertEquals(1, tailMap.size()); - -// try { -// subMap_startIncluded_endExcluded.tailMap(startKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - tailMap = subMap_startIncluded_endIncluded.tailMap(startKey); - assertEquals(1, tailMap.size()); - - startKey = new Integer(110).toString(); - try { - subMap_default.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - subMap_startExcluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - subMap_startIncluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - subMap_startIncluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } - - public void test_SubMap_values() { - Collection values = subMap_default.values(); - - assertFalse(values.isEmpty()); - assertTrue(values.contains(100)); - for (int i = 101; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertFalse(values.contains(109)); - - values = subMap_startExcluded_endExcluded.values(); - assertFalse(values.isEmpty()); - assertFalse(values.contains(100)); - for (int i = 101; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertFalse(values.contains(109)); - - values = subMap_startExcluded_endIncluded.values(); - assertFalse(values.isEmpty()); - assertFalse(values.contains(100)); - for (int i = 101; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertTrue(values.contains(109)); - - values = subMap_startIncluded_endExcluded.values(); - assertFalse(values.isEmpty()); - assertTrue(values.contains(100)); - for (int i = 101; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertFalse(values.contains(109)); - - values = subMap_startIncluded_endIncluded.values(); - assertFalse(values.isEmpty()); - assertTrue(values.contains(100)); - for (int i = 100; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertTrue(values.contains(109)); - } - - public void test_SubMap_size() { - assertEquals(9, subMap_default.size()); - assertEquals(8, subMap_startExcluded_endExcluded.size()); - assertEquals(9, subMap_startExcluded_endIncluded.size()); - assertEquals(9, subMap_startIncluded_endExcluded.size()); - assertEquals(10, subMap_startIncluded_endIncluded.size()); - - assertEquals(9, subMap_default_comparator.size()); - assertEquals(8, subMap_startExcluded_endExcluded_comparator.size()); - assertEquals(9, subMap_startExcluded_endIncluded_comparator.size()); - assertEquals(9, subMap_startIncluded_endExcluded_comparator.size()); - assertEquals(10, subMap_startIncluded_endIncluded_comparator.size()); - } - - public void test_SubMap_readObject() throws Exception { - // SerializationTest.verifySelf(subMap_default); - // SerializationTest.verifySelf(subMap_startExcluded_endExcluded); - // SerializationTest.verifySelf(subMap_startExcluded_endIncluded); - // SerializationTest.verifySelf(subMap_startIncluded_endExcluded); - // SerializationTest.verifySelf(subMap_startIncluded_endIncluded); - } - - public void test_AscendingSubMap_ceilingEntry() { - String key = new Integer(99).toString(); - assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key)); - assertNull(navigableMap_startExcluded_endIncluded.ceilingEntry(key)); - assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key)); - assertNull(navigableMap_startIncluded_endIncluded.ceilingEntry(key)); - - key = new Integer(100).toString(); - assertEquals(101, navigableMap_startExcluded_endExcluded.ceilingEntry( - key).getValue()); - assertEquals(101, navigableMap_startExcluded_endIncluded.ceilingEntry( - key).getValue()); - assertEquals(100, navigableMap_startIncluded_endExcluded.ceilingEntry( - key).getValue()); - assertEquals(100, navigableMap_startIncluded_endIncluded.ceilingEntry( - key).getValue()); - - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, navigableMap_startExcluded_endExcluded - .ceilingEntry(key).getValue()); - assertEquals(i, navigableMap_startExcluded_endIncluded - .ceilingEntry(key).getValue()); - assertEquals(i, navigableMap_startIncluded_endExcluded - .ceilingEntry(key).getValue()); - assertEquals(i, navigableMap_startIncluded_endIncluded - .ceilingEntry(key).getValue()); - - } - - key = new Integer(109).toString(); - assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key)); - assertEquals(109, navigableMap_startExcluded_endIncluded.ceilingEntry( - key).getValue()); - assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key)); - assertEquals(109, navigableMap_startIncluded_endIncluded.ceilingEntry( - key).getValue()); - - key = new Integer(110).toString(); - assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key)); - assertNull(navigableMap_startExcluded_endIncluded.ceilingEntry(key)); - assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key)); - assertNull(navigableMap_startIncluded_endIncluded.ceilingEntry(key)); - } - - - public void test_AscendingSubMap_floorEntry() { - String key = new Integer(99).toString(); - assertEquals(108, navigableMap_startExcluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startExcluded_endIncluded - .floorEntry(key).getValue()); - assertEquals(108, navigableMap_startIncluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startIncluded_endIncluded - .floorEntry(key).getValue()); - - key = new Integer(100).toString(); - assertNull(navigableMap_startExcluded_endExcluded.floorEntry(key)); - assertNull(navigableMap_startExcluded_endIncluded.floorEntry(key)); - assertEquals(100, navigableMap_startIncluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(100, navigableMap_startIncluded_endIncluded - .floorEntry(key).getValue()); - - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, navigableMap_startExcluded_endExcluded.floorEntry( - key).getValue()); - assertEquals(i, navigableMap_startExcluded_endIncluded.floorEntry( - key).getValue()); - assertEquals(i, navigableMap_startIncluded_endExcluded.floorEntry( - key).getValue()); - assertEquals(i, navigableMap_startIncluded_endIncluded.floorEntry( - key).getValue()); - - } - - key = new Integer(109).toString(); - assertEquals(108, navigableMap_startExcluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startExcluded_endIncluded - .floorEntry(key).getValue()); - assertEquals(108, navigableMap_startIncluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startIncluded_endIncluded - .floorEntry(key).getValue()); - - key = new Integer(110).toString(); - assertEquals(108, navigableMap_startExcluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startExcluded_endIncluded - .floorEntry(key).getValue()); - assertEquals(108, navigableMap_startIncluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startIncluded_endIncluded - .floorEntry(key).getValue()); - } - - public void test_AscendingSubMap_pollFirstEntry() { - assertEquals(101, navigableMap_startExcluded_endExcluded - .pollFirstEntry().getValue()); - assertEquals(102, navigableMap_startExcluded_endIncluded - .pollFirstEntry().getValue()); - assertEquals(100, navigableMap_startIncluded_endExcluded - .pollFirstEntry().getValue()); - assertEquals(103, navigableMap_startIncluded_endIncluded - .pollFirstEntry().getValue()); - } - - public void test_AscendingSubMap_pollLastEntry() { - assertEquals(108, navigableMap_startExcluded_endExcluded - .pollLastEntry().getValue()); - assertEquals(109, navigableMap_startExcluded_endIncluded - .pollLastEntry().getValue()); - assertEquals(107, navigableMap_startIncluded_endExcluded - .pollLastEntry().getValue()); - assertEquals(106, navigableMap_startIncluded_endIncluded - .pollLastEntry().getValue()); - } - - public void test_AscendingSubMap_entrySet() { - assertEquals(8, navigableMap_startExcluded_endExcluded.entrySet() - .size()); - assertEquals(9, navigableMap_startExcluded_endIncluded.entrySet() - .size()); - assertEquals(9, navigableMap_startIncluded_endExcluded.entrySet() - .size()); - assertEquals(10, navigableMap_startIncluded_endIncluded.entrySet() - .size()); - } - - public void test_AscendingSubMap_subMap() { - Set entrySet; - Entry startEntry, endEntry; - int startIndex, endIndex; - SortedMap subMap; - Iterator subMapSetIterator; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - Iterator startIterator = entrySet.iterator(); - while (startIterator.hasNext()) { - startEntry = (Entry) startIterator.next(); - startIndex = (Integer) startEntry.getValue(); - Iterator endIterator = entrySet.iterator(); - while (endIterator.hasNext()) { - endEntry = (Entry) endIterator.next(); - endIndex = (Integer) endEntry.getValue(); - - if (startIndex > endIndex) { - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), endEntry.getKey()); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), false, endEntry.getKey(), - false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), false, endEntry.getKey(), - true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), true, endEntry.getKey(), - false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), true, endEntry.getKey(), - true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subMap = navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), endEntry.getKey()); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex; index < endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - - subMap = navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), false, endEntry.getKey(), - false); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex + 1; index < endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - - subMap = navigableMap_startExcluded_endExcluded - .subMap(startEntry.getKey(), false, endEntry - .getKey(), true); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex + 1; index < endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - - subMap = navigableMap_startExcluded_endExcluded - .subMap(startEntry.getKey(), true, endEntry - .getKey(), false); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex; index < endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - - subMap = navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), true, endEntry.getKey(), true); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex; index <= endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - } - } - } - } - - - - - public void test_DescendingSubMapEntrySet_subSet() { - Set entrySet, subSet; - NavigableSet descendingSubMapEntrySet; - Entry startEntry, endEntry; - Iterator subSetIterator; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - Iterator iteratorStart = descendingSubMapEntrySet.iterator(); - while (iteratorStart.hasNext()) { - startEntry = (Entry) iteratorStart.next(); - Iterator iteratorEnd = descendingSubMapEntrySet.iterator(); - while (iteratorEnd.hasNext()) { - endEntry = (Entry) iteratorEnd.next(); - int startIndex = (Integer) startEntry.getValue(); - int endIndex = (Integer) endEntry.getValue(); - if (startIndex < endIndex) { - try { - descendingSubMapEntrySet.subSet(startEntry, - endEntry); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = descendingSubMapEntrySet.subSet(startEntry, - endEntry); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - false, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator - .hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - false, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator - .hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - true, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - true, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - } - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - // [2...0] - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - Iterator iterator = descendingSubMapEntrySet.iterator(); - startEntry = (Entry) iterator.next(); - iterator.next(); - endEntry = (Entry) iterator.next(); - subSet = descendingSubMapEntrySet.subSet(startEntry, endEntry); - assertEquals(2, subSet.size()); - - subSet = descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(199, ((Entry) subSetIterator.next()).getValue()); - - subSet = descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(199, ((Entry) subSetIterator.next()).getValue()); - assertEquals(198, ((Entry) subSetIterator.next()).getValue()); - - subSet = descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, false); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(2, ((Entry) subSetIterator.next()).getValue()); - assertEquals(199, ((Entry) subSetIterator.next()).getValue()); - - subSet = descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, true); - assertEquals(3, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(2, ((Entry) subSetIterator.next()).getValue()); - assertEquals(199, ((Entry) subSetIterator.next()).getValue()); - assertEquals(198, ((Entry) subSetIterator.next()).getValue()); - } - - // With Comnparator - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - Iterator iteratorStart = descendingSubMapEntrySet.iterator(); - while (iteratorStart.hasNext()) { - startEntry = (Entry) iteratorStart.next(); - Iterator iteratorEnd = descendingSubMapEntrySet.iterator(); - while (iteratorEnd.hasNext()) { - endEntry = (Entry) iteratorEnd.next(); - int startIndex = (Integer) startEntry.getValue(); - int endIndex = (Integer) endEntry.getValue(); - if (startIndex < endIndex) { - try { - descendingSubMapEntrySet.subSet(startEntry, - endEntry); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = descendingSubMapEntrySet.subSet(startEntry, - endEntry); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - false, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator - .hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - false, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator - .hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - true, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - true, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - } - } - } - } - } - - public void test_DescendingSubMapEntrySet_lower() { - Set entrySet, subSet; - NavigableSet descendingSubMapEntrySet; - Iterator iterator; - Entry entry, lowerEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - - // System.out.println(descendingSubMapEntrySet); - // System.out.println(tm); - Object afterEnd = this.subMap_default_afterEnd_109.entrySet() - .iterator().next(); - // System.out.println("o:" + afterEnd); - Object x = descendingSubMapEntrySet.lower(afterEnd); - // System.out.println("x:" + x); - assertNull(x); - Object beforeStart = this.subMap_default_beforeStart_100.entrySet() - .iterator().next(); - // System.out.println("before: " + beforeStart); - Object y = descendingSubMapEntrySet.lower(beforeStart); - // System.out.println("y: " + y); - assertNotNull(y); - assertEquals(101, (((Entry) y).getValue())); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - iterator.next();// 2 - iterator.next();// 199 - entry = (Entry) iterator.next();// 198 - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - assertEquals(199, lowerEntry.getValue()); - } - } - - public void test_DescendingSubMapEntrySet_higher() { - Set entrySet, subSet; - NavigableSet descendingSubMapEntrySet; - Iterator iterator; - Entry entry, higherEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - - Object afterEnd = this.subMap_default_afterEnd_109.entrySet() - .iterator().next(); - Object x = descendingSubMapEntrySet.higher(afterEnd); - assertNotNull(x); - assertEquals(108, ((Entry) x).getValue()); - Object beforeStart = this.subMap_default_beforeStart_100.entrySet() - .iterator().next(); - Object y = descendingSubMapEntrySet.higher(beforeStart); - assertNull(y); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - iterator.next();// 2 - iterator.next();// 199 - entry = (Entry) iterator.next();// 198 - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - assertEquals(197, higherEntry.getValue()); - } - - // With Comparator - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - - Object afterEnd = this.subMap_default_afterEnd_109.entrySet() - .iterator().next(); - Object x = descendingSubMapEntrySet.higher(afterEnd); - assertNotNull(x); - assertEquals(108, ((Entry) x).getValue()); - Object beforeStart = this.subMap_default_beforeStart_100.entrySet() - .iterator().next(); - Object y = descendingSubMapEntrySet.higher(beforeStart); - assertNull(y); - } - } - - public void test_DescendingSubMapEntrySet_ceiling() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet, descendingSet; - Entry entry; - Entry[] entryArray; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 108; i < entryArray.length; i++) { - entry = (Entry) descendingSet.ceiling(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - - // System.out.println(descendingSet); - // System.out.println(tm); - Object afterEnd = this.subMap_default_afterEnd_109.entrySet() - .iterator().next(); - // System.out.println("o:" + afterEnd);//110 - Object x = descendingSet.ceiling(afterEnd); - assertNotNull(x); - // System.out.println("x:" + x); - assertEquals(108, ((Entry) x).getValue()); - Object beforeStart = this.subMap_default_beforeStart_100.entrySet() - .iterator().next(); - // System.out.println("before: " + beforeStart);//0 - Object y = descendingSet.ceiling(beforeStart); - assertNull(y); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 109; i < entryArray.length; i++) { - entry = (Entry) descendingSet.ceiling(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 108; i < entryArray.length; i++) { - entry = (Entry) descendingSet.ceiling(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 109; i < entryArray.length; i++) { - entry = (Entry) descendingSet.ceiling(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - Iterator iterator = descendingSet.iterator(); - Entry ceilingEntry; - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - ceilingEntry = (Entry) descendingSet.ceiling(entry); - assertEquals(entry, ceilingEntry); - } - } - - } - - public void test_AscendingSubMapKeySet_first() { - NavigableSet keySet; - String firstKey1 = new Integer(100).toString(); - String firstKey2 = new Integer(101).toString(); - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - assertEquals(firstKey2, keySet.first()); - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - assertEquals(firstKey2, keySet.first()); - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - assertEquals(firstKey1, keySet.first()); - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - assertEquals(firstKey1, keySet.first()); - } - - - - - public void test_AscendingSubMapKeySet_last() { - NavigableSet keySet; - String firstKey1 = new Integer(108).toString(); - String firstKey2 = new Integer(109).toString(); - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - assertEquals(firstKey1, keySet.last()); - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - assertEquals(firstKey2, keySet.last()); - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - assertEquals(firstKey1, keySet.last()); - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - assertEquals(firstKey2, keySet.last()); - } - - public void test_AscendingSubMapKeySet_pollFirst_startExcluded_endExcluded() { - NavigableSet keySet = navigableMap_startExcluded_endExcluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(8, keySet.size()); - for (int value = 101; value < 109; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollFirst_startExcluded_endIncluded() { - NavigableSet keySet = navigableMap_startExcluded_endIncluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 101; value < 110; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollFirst_startIncluded_endExcluded() { - NavigableSet keySet = navigableMap_startIncluded_endExcluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 100; value < 109; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollFirst_startIncluded_endIncluded() { - NavigableSet keySet = navigableMap_startIncluded_endIncluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(10, keySet.size()); - for (int value = 100; value < 110; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollFirst() { - String endKey = new Integer(2).toString(); - NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet(); - assertEquals(new Integer(0).toString(), keySet.pollFirst()); - - keySet = tm.tailMap(endKey, true).navigableKeySet(); - assertEquals(new Integer(2).toString(), keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollLast_startExcluded_endExcluded() { - NavigableSet keySet = navigableMap_startExcluded_endExcluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(8, keySet.size()); - for (int value = 108; value > 100; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_AscendingSubMapKeySet_pollLast_startExcluded_endIncluded() { - NavigableSet keySet = navigableMap_startExcluded_endIncluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 109; value > 100; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_AscendingSubMapKeySet_pollLast_startIncluded_endExcluded() { - NavigableSet keySet = navigableMap_startIncluded_endExcluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 108; value > 99; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_AscendingSubMapKeySet_pollLast_startIncluded_endIncluded() { - NavigableSet keySet = navigableMap_startIncluded_endIncluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(10, keySet.size()); - for (int value = 109; value > 99; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_AscendingSubMapKeySet_pollLast() { - String endKey = new Integer(2).toString(); - NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet(); - assertEquals(new Integer(2).toString(), keySet.pollLast()); - - keySet = tm.tailMap(endKey, true).navigableKeySet(); - assertEquals(new Integer(999).toString(), keySet.pollLast()); - } - - - - public void test_AscendingSubMapKeySet_headSet() { - NavigableSet keySet; - SortedSet headSet; - String endKey, key; - Iterator iterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); -// try { -// keySet.headSet(endKey, true).size(); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - endKey = new Integer(101).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int index; - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); -// try { -// keySet.headSet(endKey, true); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - endKey = new Integer(101).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - endKey = new Integer(101).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(102, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - endKey = new Integer(101).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(102, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - key = new Integer(1).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next(); - endKey = (String) iterator.next(); - headSet = keySet.headSet(endKey, false); - assertEquals(1, headSet.size()); - Iterator headSetIterator = headSet.iterator(); - assertEquals(new Integer(0).toString(), headSetIterator.next()); - assertFalse(headSetIterator.hasNext()); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.headSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - headSet = keySet.headSet(endKey, true); - assertEquals(2, headSet.size()); - headSetIterator = headSet.iterator(); - assertEquals(new Integer(0).toString(), headSetIterator.next()); - assertEquals(new Integer(1).toString(), headSetIterator.next()); - assertFalse(headSetIterator.hasNext()); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.headSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); -// try { -// keySet.headSet(endKey, true).size(); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - endKey = new Integer(101).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); -// try { -// keySet.headSet(endKey, true); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - - endKey = new Integer(101).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator) - .navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - endKey = new Integer(101).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(102, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator) - .navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - endKey = new Integer(101).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(102, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - key = new Integer(1).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next(); - endKey = (String) iterator.next(); - headSet = keySet.headSet(endKey, false); - assertEquals(1, headSet.size()); - headSetIterator = headSet.iterator(); - assertEquals(new Integer(0).toString(), headSetIterator.next()); - assertFalse(headSetIterator.hasNext()); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.headSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - headSet = keySet.headSet(endKey, true); - assertEquals(2, headSet.size()); - headSetIterator = headSet.iterator(); - assertEquals(new Integer(0).toString(), headSetIterator.next()); - assertEquals(new Integer(1).toString(), headSetIterator.next()); - assertFalse(headSetIterator.hasNext()); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.headSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - } - - public void test_AscendingSubMapKeySet_remove() { - SortedMap subMap_startExcluded_endExcluded_rm = tm.subMap( - objArray[100].toString(), false, objArray[109].toString(), - false); - assertNull(subMap_startExcluded_endExcluded_rm.remove("0")); - try { - subMap_startExcluded_endExcluded_rm.remove(null); - fail("should throw NPE"); - } catch (Exception e) { - // Expected - } - for (int i = 101; i < 108; i++) { - assertNotNull(subMap_startExcluded_endExcluded_rm - .remove(new Integer(i).toString())); - } - } - - public void test_AscendingSubMapKeySet_tailSet() { - NavigableSet keySet; - SortedSet tailSet; - String startKey, key; - Iterator iterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - int index; - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; index < 109; index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - - startKey = new Integer(101).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(108, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(108, j); - } - - startKey = new Integer(109).toString(); -// try { -// keySet.tailSet(startKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } -// try { -// keySet.tailSet(startKey, true); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(109, j); - } - - startKey = new Integer(109).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(108, index); - - startKey = new Integer(101).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(108, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(108, j); - } - - startKey = new Integer(109).toString(); -// try { -// keySet.tailSet(startKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } -// try { -// keySet.tailSet(startKey, true); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - startKey = new Integer(100).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(101).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(109, j); - } - - startKey = new Integer(109).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - String endKey = new Integer(1).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next(); - startKey = (String) iterator.next(); - tailSet = keySet.tailSet(startKey); - assertEquals(1, tailSet.size()); - Iterator tailSetIterator = tailSet.iterator(); - assertEquals(endKey, tailSetIterator.next()); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.tailSet(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - tailSet = keySet.tailSet(startKey, true); - assertEquals(1, tailSet.size()); - tailSetIterator = tailSet.iterator(); - assertEquals(endKey, tailSetIterator.next()); - - tailSet = keySet.tailSet(startKey, false); - assertEquals(0, tailSet.size()); - tailSetIterator = tailSet.iterator(); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.tailSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - try { - keySet.tailSet(null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; index < 109; index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - - startKey = new Integer(101).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(108, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(108, j); - } - - startKey = new Integer(109).toString(); -// try { -// keySet.tailSet(startKey); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } -// try { -// keySet.tailSet(startKey, true); -// fail("should throw IllegalArgumentException"); -// } catch (IllegalArgumentException e) { -// // Expected -// } - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(109, j); - } - - startKey = new Integer(109).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } - - public void test_AscendingSubMapKeySet_subSet() { - NavigableSet keySet; - SortedSet subSet; - String startKey, endKey, key; - Iterator startIterator, endIterator, subSetIterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - startIterator = keySet.iterator(); - while (startIterator.hasNext()) { - startKey = (String) startIterator.next(); - endIterator = keySet.iterator(); - while (endIterator.hasNext()) { - endKey = (String) endIterator.next(); - int startIndex = Integer.valueOf(startKey); - int endIndex = Integer.valueOf(endKey); - if (startIndex > endIndex) { - try { - keySet.subSet(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = keySet.subSet(startKey, endKey); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, false, endKey, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, false, endKey, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, true, endKey, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, true, endKey, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - } - } - } - - key = new Integer(1).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - Iterator iterator = keySet.iterator(); - startKey = (String) iterator.next(); - endKey = (String) iterator.next(); - - subSet = keySet.subSet(startKey, endKey); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, false, endKey, false); - assertEquals(0, subSet.size()); - - subSet = keySet.subSet(startKey, false, endKey, true); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(1).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, true, endKey, false); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, true, endKey, true); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - assertEquals(new Integer(1).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - keySet.subSet(null, null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, endKey); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, endKey, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, endKey, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, endKey, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, endKey, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - startIterator = keySet.iterator(); - while (startIterator.hasNext()) { - startKey = (String) startIterator.next(); - endIterator = keySet.iterator(); - while (endIterator.hasNext()) { - endKey = (String) endIterator.next(); - int startIndex = Integer.valueOf(startKey); - int endIndex = Integer.valueOf(endKey); - if (startIndex > endIndex) { - try { - keySet.subSet(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = keySet.subSet(startKey, endKey); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, false, endKey, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, false, endKey, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, true, endKey, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, true, endKey, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - } - } - } - - key = new Integer(1).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - startKey = (String) iterator.next(); - endKey = (String) iterator.next(); - - subSet = keySet.subSet(startKey, endKey); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, false, endKey, false); - assertEquals(0, subSet.size()); - - subSet = keySet.subSet(startKey, false, endKey, true); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(1).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, true, endKey, false); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, true, endKey, true); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - assertEquals(new Integer(1).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - keySet.subSet(null, null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, endKey); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, endKey, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, endKey, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, endKey, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, endKey, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - } - - public void test_AscendingSubMapKeySet_lower() { - NavigableSet keySet; - Iterator iterator; - String key, lowerKey; - int value, lowerValue; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.lower(key); - if (value > 101) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value - 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.lower(key); - if (value > 101) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value - 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.lower(key); - if (value > 100) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value - 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.lower(key); - if (value > 100) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value - 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next();// 0 - String expectedLowerKey = (String) iterator.next();// 1 - assertEquals(expectedLowerKey, keySet.lower(iterator.next())); - - try { - keySet.lower(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNull(keySet.lower(key)); - - key = new Integer(0).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.lower(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNotNull(keySet.lower(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNotNull(keySet.lower(key)); - } - - public void test_AscendingSubMapKeySet_higher() { - NavigableSet keySet; - Iterator iterator; - String key, lowerKey; - int value, lowerValue; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.higher(key); - if (value < 108) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.higher(key); - if (value < 109) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.higher(key); - if (value < 108) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.higher(key); - if (value < 109) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next();// 0 - iterator.next();// 1 - lowerKey = (String) keySet.higher(iterator.next()); - String expectedLowerKey = (String) iterator.next(); - assertEquals(expectedLowerKey, lowerKey); - - try { - keySet.higher(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(0).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.higher(key)); - } - - public void test_AscendingSubMapKeySet_ceiling() { - NavigableSet keySet; - String key; - String[] keyArray; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 101; i < keyArray.length; i++) { - key = (String) keySet.ceiling(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 101; i < keyArray.length; i++) { - key = (String) keySet.ceiling(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 100; i < keyArray.length; i++) { - key = (String) keySet.ceiling(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 100; i < keyArray.length; i++) { - key = (String) keySet.ceiling(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - Iterator iterator = keySet.iterator(); - iterator.next(); - assertEquals(new Integer(1).toString(), keySet.ceiling(iterator.next())); - - try { - keySet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertEquals(key, keySet.ceiling(key)); - - key = new Integer(0).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.higher(key)); - } - - public void test_AscendingSubMapKeySet_floor() { - NavigableSet keySet; - String key; - String[] keyArray; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 101; i < keyArray.length; i++) { - key = (String) keySet.floor(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 101; i < keyArray.length; i++) { - key = (String) keySet.floor(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 100; i < keyArray.length; i++) { - key = (String) keySet.floor(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 100; i < keyArray.length; i++) { - key = (String) keySet.floor(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - Iterator iterator = keySet.iterator(); - iterator.next(); - assertEquals(new Integer(1).toString(), keySet.floor(iterator.next())); - - try { - keySet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertEquals(key, keySet.floor(key)); - - key = new Integer(0).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.floor(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertEquals(key, keySet.floor(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertEquals(new Integer(998).toString(), keySet.floor(key)); - } - - public void test_BoundedEntryIterator_next() { - Iterator iterator = subMap_default.entrySet().iterator(); - assertTrue(iterator.hasNext()); - for (int i = 100; iterator.hasNext(); i++) { - assertEquals(i, ((Entry) iterator.next()).getValue()); - } - - try { - iterator.next(); - fail("should throw java.util.NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - } - - public void test_BoundedKeyIterator_next() { - Iterator iterator = subMap_default.keySet().iterator(); - assertTrue(iterator.hasNext()); - for (int i = 100; iterator.hasNext(); i++) { - assertEquals(new Integer(i).toString(), iterator.next()); - } - - try { - iterator.next(); - fail("should throw java.util.NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - public void test_BoundedValueIterator_next() { - String startKey = new Integer(101).toString(); - String endKey = new Integer(108).toString(); - - Collection values = tm.subMap(startKey, endKey).values(); - Iterator iter = values.iterator(); - for (int i = 101; i < 108; i++) { - assertEquals(i, iter.next()); - } - try { - iter.next(); - fail("should throw java.util.NoSuchElementException"); - } catch (Exception e) { - // Expected - } - } - - /* - * SubMapEntrySet - */ - public void test_SubMapEntrySet_Constructor() { - } - - public void test_SubMapEntrySet_contains() { - // covered in test_SubMapEntrySet_remove - } - - public void test_SubMapEntrySet_iterator() { - Set entrySet = subMap_default.entrySet(); - Iterator iterator; - Entry entry; - Integer value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startExcluded_endExcluded.entrySet(); - value = new Integer(101); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startExcluded_endIncluded.entrySet(); - value = new Integer(101); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(110, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startIncluded_endExcluded.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startIncluded_endIncluded.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(110, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - String startKey = new Integer(-1).toString(); - String endKey = new Integer(0).toString(); - SortedMap subMap = tm.subMap(startKey, endKey); - entrySet = subMap.entrySet(); - iterator = entrySet.iterator(); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - entrySet = subMap.entrySet(); - iterator = entrySet.iterator(); - assertEquals(0, ((Entry) iterator.next()).getValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - endKey = new Integer(2000).toString(); - subMap = tm.subMap(startKey, endKey); - entrySet = subMap.entrySet(); - iterator = entrySet.iterator(); - for (int i = 0; i < subMap.size(); i++) { - iterator.next(); - } - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - startKey = new Integer(9).toString(); - endKey = new Integer(100).toString(); - try { - tm.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // With Comparator - entrySet = subMap_default_comparator.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - value = new Integer(101); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - value = new Integer(101); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(110, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startIncluded_endIncluded_comparator.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(110, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - public void test_SubMapEntrySet_remove() { - Set entrySet = subMap_default.entrySet(); - assertFalse(entrySet.remove(null)); - int size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - - entrySet = subMap_startExcluded_endExcluded.entrySet(); - assertFalse(entrySet.remove(null)); - size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - - entrySet = subMap_startExcluded_endIncluded.entrySet(); - assertFalse(entrySet.remove(null)); - size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - - entrySet = subMap_startIncluded_endExcluded.entrySet(); - assertFalse(entrySet.remove(null)); - size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - - entrySet = subMap_startIncluded_endIncluded.entrySet(); - assertFalse(entrySet.remove(null)); - size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - } - - public void test_SubMapEntrySet_isEmpty() { - assertFalse(subMap_default.entrySet().isEmpty()); - assertFalse(subMap_startExcluded_endExcluded.entrySet().isEmpty()); - assertFalse(subMap_startExcluded_endIncluded.entrySet().isEmpty()); - assertFalse(subMap_startIncluded_endExcluded.entrySet().isEmpty()); - assertFalse(subMap_startIncluded_endIncluded.entrySet().isEmpty()); - - String startKey = new Integer(0).toString(); - String endKey = startKey; - SortedMap subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.entrySet().isEmpty()); - - startKey = new Integer(-1).toString(); - subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.entrySet().isEmpty()); - - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - assertFalse(subMap.entrySet().isEmpty()); - } - - public void test_SubMapEntrySet_size() { - assertEquals(9, subMap_default.entrySet().size()); - assertEquals(8, subMap_startExcluded_endExcluded.entrySet().size()); - assertEquals(9, subMap_startExcluded_endIncluded.entrySet().size()); - assertEquals(9, subMap_startIncluded_endExcluded.entrySet().size()); - assertEquals(10, subMap_startIncluded_endIncluded.entrySet().size()); - - String startKey = new Integer(0).toString(); - String endKey = new Integer(2).toString(); - SortedMap subMap = tm.subMap(startKey, endKey); - assertEquals(112, subMap.entrySet().size()); - - startKey = new Integer(0).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.entrySet().size()); - - startKey = new Integer(-1).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.entrySet().size()); - - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - assertEquals(1, subMap.entrySet().size()); - - startKey = new Integer(999).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.entrySet().size()); - } - - /* - * SubMapKeySet - */ - public void test_SubMapKeySet_Constructor() { - // covered in other test - } - - public void test_SubMapKeySet_iterator() { - Set keySet = subMap_default.keySet(); - Iterator iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startExcluded_endExcluded.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(101 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startExcluded_endIncluded.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(101 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startIncluded_endExcluded.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startIncluded_endIncluded.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - // With Comparator - keySet = subMap_default_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startExcluded_endExcluded_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(101 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startExcluded_endIncluded_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(101 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startIncluded_endExcluded_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startIncluded_endIncluded_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - public void test_SubMapKeySet_isEmpty() { - assertFalse(subMap_default.keySet().isEmpty()); - assertFalse(subMap_startExcluded_endExcluded.keySet().isEmpty()); - assertFalse(subMap_startExcluded_endIncluded.keySet().isEmpty()); - assertFalse(subMap_startIncluded_endExcluded.keySet().isEmpty()); - assertFalse(subMap_startIncluded_endIncluded.keySet().isEmpty()); - - String startKey = new Integer(0).toString(); - String endKey = startKey; - SortedMap subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.keySet().isEmpty()); - - startKey = new Integer(999).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.keySet().isEmpty()); - - startKey = new Integer(-1).toString(); - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - assertFalse(subMap.keySet().isEmpty()); - - endKey = new Integer(0).toString(); - subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.keySet().isEmpty()); - } - - public void test_SubMapKeySet_contains() { - Set keySet = subMap_default.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - String key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertTrue(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - - keySet = subMap_startExcluded_endExcluded.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertFalse(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - - keySet = subMap_startExcluded_endIncluded.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertFalse(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertTrue(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - - keySet = subMap_startIncluded_endExcluded.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertTrue(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - - keySet = subMap_startIncluded_endIncluded.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertTrue(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertTrue(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - } - - public void test_SubMapKeySet_size() { - assertEquals(9, subMap_default.keySet().size()); - assertEquals(8, subMap_startExcluded_endExcluded.keySet().size()); - assertEquals(9, subMap_startExcluded_endIncluded.keySet().size()); - assertEquals(9, subMap_startIncluded_endExcluded.keySet().size()); - assertEquals(10, subMap_startIncluded_endIncluded.keySet().size()); - - String startKey = new Integer(0).toString(); - String endKey = new Integer(2).toString(); - SortedMap subMap = tm.subMap(startKey, endKey); - assertEquals(112, subMap.keySet().size()); - - startKey = new Integer(0).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.keySet().size()); - - startKey = new Integer(-1).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.keySet().size()); - - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - assertEquals(1, subMap.keySet().size()); - - startKey = new Integer(999).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.keySet().size()); - } - - public void test_SubMapKeySet_remove() { - Set keySet = subMap_default.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - int size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - - keySet = subMap_startExcluded_endExcluded.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - - keySet = subMap_startExcluded_endIncluded.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - - keySet = subMap_startIncluded_endExcluded.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - - keySet = subMap_startIncluded_endIncluded.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - } - - /* - * AscendingSubMapEntrySet - */ - - public void test_AscendingSubMapEntrySet_comparator() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - assertNull(ascendingSubMapEntrySet.comparator()); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - assertNull(ascendingSubMapEntrySet.comparator()); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - assertNull(ascendingSubMapEntrySet.comparator()); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - assertNull(ascendingSubMapEntrySet.comparator()); - } - } - - public void test_AscendingSubMapEntrySet_descendingSet() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet, descendingSet; - Entry entry; - int value; - Iterator iterator; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - iterator = descendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 108; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(100, value); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - iterator = descendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 109; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(100, value); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - iterator = descendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 108; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(99, value); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - iterator = descendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 109; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(99, value); - } - } - - public void test_AscendingSubMapEntrySet_descendingIterator() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - Entry entry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - for (value = 108; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(100, value); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - for (value = 109; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(100, value); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - for (value = 108; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(99, value); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - for (value = 109; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(99, value); - } - - String startKey = new Integer(2).toString(); - entrySet = tm.headMap(startKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - assertEquals(2, ((Entry) iterator.next()).getValue()); - } - } - - public void test_AscendingSubMapEntrySet_pollFirst_startExcluded_endExcluded() { - Set entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 101; value < 109; value++) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty. - assertNull(ascendingSubMapEntrySet.pollFirst()); - } - } - - public void test_AscendingSubMapEntrySet_pollFirst_startExcluded_endIncluded() { - Set entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 101; value < 110; value++) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty. - assertNull(ascendingSubMapEntrySet.pollFirst()); - } - } - - public void test_AscendingSubMapEntrySet_pollFirst_startIncluded_endExcluded() { - Set entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 100; value < 109; value++) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty. - assertNull(ascendingSubMapEntrySet.pollFirst()); - } - } - - public void test_AscendingSubMapEntrySet_pollFirst_startIncluded_endIncluded() { - Set entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 100; value < 110; value++) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty. - assertNull(ascendingSubMapEntrySet.pollFirst()); - } - } - - public void test_AscendingSubMapEntrySet_pollLast_startExcluded_endExcluded() { - Set entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 108; value > 100; value--) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollLast(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty - assertNull(ascendingSubMapEntrySet.pollLast()); - } - - // NavigableMap ascendingSubMap = tm.headMap("2", true); - // Set entrySet = ascendingSubMap.entrySet(); - // Object last; - // if (entrySet instanceof NavigableSet) { - // last = ((NavigableSet) entrySet).pollLast(); - // assertEquals("2=2", last.toString()); - // } - // - // ascendingSubMap = tm.tailMap("2", true); - // entrySet = ascendingSubMap.entrySet(); - // if (entrySet instanceof NavigableSet) { - // last = ((NavigableSet) entrySet).pollLast(); - // assertEquals("999=999", last.toString()); - // } - } - - public void test_AscendingSubMapEntrySet_pollLast_startExcluded_endIncluded() { - Set entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 109; value > 100; value--) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollLast(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty - assertNull(ascendingSubMapEntrySet.pollLast()); - } - } - - public void test_AscendingSubMapEntrySet_pollLast_startIncluded_endExcluded() { - Set entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 108; value > 99; value--) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollLast(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty - assertNull(ascendingSubMapEntrySet.pollLast()); - } - } - - public void test_AscendingSubMapEntrySet_pollLast_startIncluded_endIncluded() { - Set entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 109; value > 99; value--) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollLast(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty - assertNull(ascendingSubMapEntrySet.pollLast()); - } - } - - public void test_AscendingSubMapEntrySet_headSet() { - Set entrySet, headSet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator, headSetIterator; - Entry entry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = ascendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value - 1); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = ascendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value - 1); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = ascendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value - 1); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = ascendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value - 1); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - // NavigableMap ascendingSubMap = tm.headMap("1", true); - // entrySet = ascendingSubMap.entrySet(); - // if (entrySet instanceof SortedSet) { - // Iterator it = entrySet.iterator(); - // it.next(); - // Object end = it.next();// 1=1 - // Set headSet = ((NavigableSet) entrySet).headSet(end);// inclusive - // // false - // assertEquals(1, headSet.size()); - // } - } - - public void test_AscendingSubMapEntrySet_tailSet() { - Set entrySet, tailSet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator, tailSetIterator; - Entry entry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = ascendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = ascendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = ascendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = ascendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - // NavigableMap ascendingSubMap = tm.headMap("1", true); - // Set entrySet = ascendingSubMap.entrySet(); - // if (entrySet instanceof NavigableSet) { - // Iterator it = entrySet.iterator(); - // Object start = it.next();// 0=0 - // Set tailSet = ((NavigableSet) entrySet).tailSet(start);// default - // // inclusive - // // false - // assertEquals(1, tailSet.size()); - // } - } - - public void test_AscendingSubMapEntrySet_subSet() { - Set entrySet, subSet; - NavigableSet ascendingSubMapEntrySet; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - Iterator iteratorStart = ascendingSubMapEntrySet.iterator(); - while (iteratorStart.hasNext()) { - Entry startEntry = (Entry) iteratorStart.next(); - Iterator iteratorEnd = ascendingSubMapEntrySet.iterator(); - while (iteratorEnd.hasNext()) { - Entry endEntry = (Entry) iteratorEnd.next(); - int startIndex = (Integer) startEntry.getValue(); - int endIndex = (Integer) endEntry.getValue(); - if (startIndex > endIndex) { - try { - ascendingSubMapEntrySet - .subSet(startEntry, endEntry); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - ascendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - ascendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - ascendingSubMapEntrySet.subSet(startEntry, true, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - ascendingSubMapEntrySet.subSet(startEntry, true, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = ascendingSubMapEntrySet.subSet(startEntry, - endEntry); - Iterator subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator - .hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = ascendingSubMapEntrySet.subSet(startEntry, - false, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator - .hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = ascendingSubMapEntrySet.subSet(startEntry, - false, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator - .hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = ascendingSubMapEntrySet.subSet(startEntry, - true, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = ascendingSubMapEntrySet.subSet(startEntry, - true, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - } - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - Iterator iterator = entrySet.iterator(); - Object startEntry = iterator.next(); - iterator.next(); - Object endEntry = iterator.next(); - subSet = ascendingSubMapEntrySet.subSet(startEntry, endEntry); - assertEquals(1, subSet.size()); - - subSet = ascendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - assertEquals(1, subSet.size()); - - subSet = ascendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - assertEquals(2, subSet.size()); - - subSet = ascendingSubMapEntrySet.subSet(startEntry, true, endEntry, - false); - assertEquals(2, subSet.size()); - - subSet = ascendingSubMapEntrySet.subSet(startEntry, true, endEntry, - true); - assertEquals(3, subSet.size()); - } - } - - public void test_AscendingSubMapEntrySet_lower() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - Entry entry, lowerEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - Entry expectedEntry = (Entry) iterator.next(); - entry = (Entry) iterator.next(); - assertEquals(expectedEntry, ascendingSubMapEntrySet.lower(entry)); - } - - // With Comparator - - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startIncluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - } - - public void test_AscendingSubMapEntrySet_higher() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - Entry entry, lowerEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - entry = (Entry) iterator.next(); - Entry expectedEntry = (Entry) iterator.next(); - assertEquals(expectedEntry, ascendingSubMapEntrySet.higher(entry)); - } - - // With Comparator - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startIncluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - } - - public void test_AscendingSubMapEntrySet_ceiling() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - - Set entrySet_beyondBound; - Iterator iterator_beyondBound; - Entry beyondBoundEntry; - - Entry entry, lowerEntry; - int value = 0; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(108, value); - - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(109, value); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(108, value); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(109, value); - } - - // With Comparator - entrySet = subMap_startIncluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(109, value); - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(108, value); - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(109, value); - } - - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(108, value); - } - } - - public void test_AscendingSubMapEntrySet_floor() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - Entry entry, floorEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 101; i < 109; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 101; i < 110; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 100; i < 109; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 100; i < 110; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - // With Comparator - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 101; i < 109; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 101; i < 110; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 100; i < 109; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = subMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 100; i < 110; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - } - - @Override - protected void setUp() { - tm = newBTreeMap(); - tm_comparator = newBTreeMap(); - for (int i = 0; i < objArray.length; i++) { - Object x = objArray[i] = new Integer(i); - tm.put(x.toString(), x); - tm_comparator.put(x.toString(), x); - } - - subMap_default = tm.subMap(objArray[100].toString(), objArray[109] - .toString()); - subMap_startExcluded_endExcluded = tm.subMap(objArray[100].toString(), - false, objArray[109].toString(), false); - subMap_startExcluded_endIncluded = tm.subMap(objArray[100].toString(), - false, objArray[109].toString(), true); - subMap_startIncluded_endExcluded = tm.subMap(objArray[100].toString(), - true, objArray[109].toString(), false); - subMap_startIncluded_endIncluded = tm.subMap(objArray[100].toString(), - true, objArray[109].toString(), true); - - subMap_default_beforeStart_100 = tm.subMap(objArray[0].toString(), - objArray[1].toString()); - - subMap_default_afterEnd_109 = tm.subMap(objArray[110].toString(), - objArray[119].toString()); - - assertTrue(subMap_startExcluded_endExcluded instanceof NavigableMap); - assertTrue(subMap_startExcluded_endIncluded instanceof NavigableMap); - assertTrue(subMap_startIncluded_endExcluded instanceof NavigableMap); - assertTrue(subMap_startIncluded_endIncluded instanceof NavigableMap); - - navigableMap_startExcluded_endExcluded = (NavigableMap) subMap_startExcluded_endExcluded; - navigableMap_startExcluded_endIncluded = (NavigableMap) subMap_startExcluded_endIncluded; - navigableMap_startIncluded_endExcluded = (NavigableMap) subMap_startIncluded_endExcluded; - navigableMap_startIncluded_endIncluded = (NavigableMap) subMap_startIncluded_endIncluded; - - subMap_default_comparator = tm_comparator.subMap(objArray[100] - .toString(), objArray[109].toString()); - subMap_startExcluded_endExcluded_comparator = tm_comparator.subMap( - objArray[100].toString(), false, objArray[109].toString(), - false); - - subMap_startExcluded_endIncluded_comparator = tm_comparator - .subMap(objArray[100].toString(), false, objArray[109] - .toString(), true); - subMap_startIncluded_endExcluded_comparator = tm_comparator - .subMap(objArray[100].toString(), true, objArray[109] - .toString(), false); - subMap_startIncluded_endIncluded_comparator = tm_comparator.subMap( - objArray[100].toString(), true, objArray[109].toString(), true); - } - - @Override - protected void tearDown() { - tm.engine.close(); - tm = null; - tm_comparator = null; - - subMap_default = null; - subMap_startExcluded_endExcluded = null; - subMap_startExcluded_endIncluded = null; - subMap_startIncluded_endExcluded = null; - subMap_startIncluded_endIncluded = null; - - subMap_default_beforeStart_100 = null; - subMap_default_afterEnd_109 = null; - - subMap_default_comparator = null; - subMap_startExcluded_endExcluded_comparator = null; - subMap_startExcluded_endIncluded_comparator = null; - subMap_startIncluded_endExcluded_comparator = null; - subMap_startIncluded_endIncluded_comparator = null; - } - - public void test_lower_null() throws Exception { - NavigableMap map = tm.subMap(objArray[100].toString(), true, - objArray[100].toString(), false); - assertNull(map.ceilingKey(objArray[100].toString())); - assertNull(map.floorKey(objArray[100].toString())); - assertNull(map.lowerKey(objArray[100].toString())); - assertNull(map.higherKey(objArray[100].toString())); - assertNull(map.ceilingKey(objArray[111].toString())); - assertNull(map.floorKey(objArray[111].toString())); - assertNull(map.lowerKey(objArray[111].toString())); - assertNull(map.higherKey(objArray[111].toString())); - assertNull(map.ceilingKey(objArray[1].toString())); - assertNull(map.floorKey(objArray[1].toString())); - assertNull(map.lowerKey(objArray[1].toString())); - assertNull(map.higherKey(objArray[1].toString())); -// map = map.descendingMap(); -// assertNull(map.ceilingKey(objArray[100].toString())); -// assertNull(map.floorKey(objArray[100].toString())); -// assertNull(map.lowerKey(objArray[100].toString())); -// assertNull(map.higherKey(objArray[100].toString())); -// assertNull(map.ceilingKey(objArray[111].toString())); -// assertNull(map.floorKey(objArray[111].toString())); -// assertNull(map.lowerKey(objArray[111].toString())); -// assertNull(map.higherKey(objArray[111].toString())); -// assertNull(map.ceilingKey(objArray[1].toString())); -// assertNull(map.floorKey(objArray[1].toString())); -// assertNull(map.lowerKey(objArray[1].toString())); -// assertNull(map.higherKey(objArray[1].toString())); - } - - public void test_lower_tail() throws Exception { - NavigableMap map = tm.subMap(objArray[102].toString(), true, - objArray[103].toString(), false); - assertTrue(map.containsKey(objArray[102].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertFalse(map.containsKey(objArray[103].toString())); - assertFalse(map.containsKey(objArray[104].toString())); -// map = map.descendingMap(); -// assertTrue(map.containsKey(objArray[102].toString())); -// assertFalse(map.containsKey(objArray[101].toString())); -// assertFalse(map.containsKey(objArray[103].toString())); -// assertFalse(map.containsKey(objArray[104].toString())); - map = tm.subMap(objArray[102].toString(), true, objArray[102] - .toString(), false); - assertFalse(map.containsKey(objArray[102].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertFalse(map.containsKey(objArray[103].toString())); - assertFalse(map.containsKey(objArray[104].toString())); -// map = map.descendingMap(); -// assertFalse(map.containsKey(objArray[102].toString())); -// assertFalse(map.containsKey(objArray[101].toString())); -// assertFalse(map.containsKey(objArray[103].toString())); -// assertFalse(map.containsKey(objArray[104].toString())); - } - - public void test_contains_null() throws Exception { - NavigableMap map = tm.subMap(objArray[100].toString(), true, - objArray[100].toString(), false); - assertFalse(map.containsKey(objArray[100].toString())); - assertFalse(map.containsKey(objArray[10].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertFalse(map.containsKey(objArray[102].toString())); - assertFalse(map.containsKey(objArray[1].toString())); -// map = map.descendingMap(); -// assertFalse(map.containsKey(objArray[100].toString())); -// assertFalse(map.containsKey(objArray[10].toString())); -// assertFalse(map.containsKey(objArray[101].toString())); -// assertFalse(map.containsKey(objArray[102].toString())); -// assertFalse(map.containsKey(objArray[1].toString())); - } - - public void test_contains() throws Exception { - NavigableMap map = tm.subMap(objArray[102].toString(), true, - objArray[103].toString(), false); - assertFalse(map.containsKey(objArray[100].toString())); - assertFalse(map.containsKey(objArray[104].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertTrue(map.containsKey(objArray[102].toString())); -// map = map.descendingMap(); -// assertFalse(map.containsKey(objArray[100].toString())); -// assertFalse(map.containsKey(objArray[104].toString())); -// assertFalse(map.containsKey(objArray[101].toString())); -// assertTrue(map.containsKey(objArray[102].toString())); - } - - public void test_size() throws Exception { - NavigableMap map = tm.subMap(objArray[102].toString(), true, - objArray[103].toString(), false); - assertEquals(0, map.headMap(objArray[102].toString(), false).size()); - assertEquals(1, map.headMap(objArray[102].toString(), true).size()); - try { - assertEquals(1, map.headMap(objArray[103].toString(), true).size()); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - assertEquals(1, map.headMap(objArray[103].toString(), false).size()); - assertEquals(1, map.tailMap(objArray[102].toString(), true).size()); - assertEquals(0, map.tailMap(objArray[102].toString(), false).size()); - assertTrue(map.headMap(objArray[103].toString(), false).containsKey( - objArray[102].toString())); - try { - assertTrue(map.headMap(objArray[103].toString(), true).containsKey( - objArray[102].toString())); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - assertFalse(map.headMap(objArray[102].toString(), false).containsKey( - objArray[102].toString())); - assertTrue(map.headMap(objArray[102].toString(), true).containsKey( - objArray[102].toString())); - assertTrue(map.tailMap(objArray[102].toString(), true).containsKey( - objArray[102].toString())); - assertFalse(map.tailMap(objArray[102].toString(), true).containsKey( - objArray[103].toString())); - try { - assertEquals(0, map.tailMap(objArray[101].toString()).size()); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } -// map = map.descendingMap(); -// try { -// map = map.subMap(objArray[103].toString(), true, objArray[102] -// .toString(), true); -// fail("should throw IAE"); -// } catch (IllegalArgumentException e) { -// } - map = map.subMap(objArray[102].toString(), true, objArray[102] - .toString(), true); - assertEquals(1, map.headMap(objArray[102].toString(), true).size()); - assertEquals(0, map.headMap(objArray[102].toString(), false).size()); - try { - assertEquals(0, map.headMap(objArray[103].toString(), true).size()); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - - assertEquals(1, map.tailMap(objArray[102].toString(), true).size()); - try { - assertFalse(map.headMap(objArray[103].toString(), true) - .containsKey(objArray[102].toString())); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - assertTrue(map.headMap(objArray[102].toString(), true).containsKey( - objArray[102].toString())); - assertFalse(map.headMap(objArray[102].toString(), false).containsKey( - objArray[102].toString())); - assertTrue(map.tailMap(objArray[102].toString(), true).containsKey( - objArray[102].toString())); - assertFalse(map.tailMap(objArray[102].toString(), true).containsKey( - objArray[103].toString())); - try { - assertEquals(0, map.tailMap(objArray[101].toString()).size()); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - } - - public void test_lower() throws Exception { - NavigableMap map = tm.subMap(objArray[102].toString(), true, - objArray[103].toString(), false); - assertEquals(objArray[102].toString(), map.higherKey(objArray[101] - .toString())); - assertEquals(null, map.higherKey(objArray[102].toString())); - assertEquals(null, map.higherKey(objArray[103].toString())); - assertEquals(null, map.higherKey(objArray[104].toString())); - assertEquals(objArray[102].toString(), map.ceilingKey(objArray[101] - .toString())); - assertEquals(objArray[102].toString(), map.ceilingKey(objArray[102] - .toString())); - assertEquals(null, map.ceilingKey(objArray[103].toString())); - assertEquals(null, map.ceilingKey(objArray[104].toString())); - assertEquals(null, map.lowerKey(objArray[101].toString())); - assertEquals(null, map.lowerKey(objArray[102].toString())); - assertEquals(objArray[102].toString(), map.lowerKey(objArray[103] - .toString())); - assertEquals(objArray[102].toString(), map.lowerKey(objArray[104] - .toString())); - assertEquals(null, map.floorKey(objArray[101].toString())); - assertEquals(objArray[102].toString(), map.floorKey(objArray[102] - .toString())); - assertEquals(objArray[102].toString(), map.floorKey(objArray[103] - .toString())); - assertEquals(objArray[102].toString(), map.floorKey(objArray[104] - .toString())); -// map = map.descendingMap(); -// assertEquals(null, map.higherKey(objArray[101].toString())); -// assertEquals(null, map.higherKey(objArray[102].toString())); -// assertEquals(objArray[102].toString(), map.higherKey(objArray[103] -// .toString())); -// assertEquals(objArray[102].toString(), map.higherKey(objArray[104] -// .toString())); -// assertEquals(null, map.ceilingKey(objArray[101].toString())); -// assertEquals(objArray[102].toString(), map.ceilingKey(objArray[102] -// .toString())); -// assertEquals(objArray[102].toString(), map.ceilingKey(objArray[103] -// .toString())); -// assertEquals(objArray[102].toString(), map.ceilingKey(objArray[104] -// .toString())); -// assertEquals(objArray[102].toString(), map.lowerKey(objArray[101] -// .toString())); -// assertEquals(null, map.lowerKey(objArray[102].toString())); -// assertEquals(null, map.lowerKey(objArray[103].toString())); -// assertEquals(null, map.lowerKey(objArray[104].toString())); -// assertEquals(objArray[102].toString(), map.floorKey(objArray[101] -// .toString())); -// assertEquals(objArray[102].toString(), map.floorKey(objArray[102] -// .toString())); -// assertEquals(null, map.floorKey(objArray[103].toString())); -// assertEquals(null, map.floorKey(objArray[104].toString())); - } - - public void test_lowerkey() throws Exception { - try { - tm.subMap(objArray[100].toString(), true, objArray[100].toString(), - false).descendingMap().firstKey(); - fail("should throw NoSuchElementException"); - } catch (Exception e) { - // expected - } - try { - tm.subMap(objArray[100].toString(), true, objArray[100].toString(), - false).descendingMap().lastKey(); - fail("should throw NoSuchElementException"); - } catch (Exception e) { - // expected - } - try { - tm.subMap(objArray[100].toString(), true, objArray[100].toString(), - false).firstKey(); - fail("should throw NoSuchElementException"); - } catch (Exception e) { - // expected - } - try { - tm.subMap(objArray[100].toString(), true, objArray[100].toString(), - false).lastKey(); - fail("should throw NoSuchElementException"); - } catch (Exception e) { - // expected - } - - } - - public void test_headMap() throws Exception { - BTreeMap tree = newBTreeMap(); - tree.put(new Integer(0), "11"); - tree.put(new Integer(1), "ads"); - Map submap = tree.subMap(tree.firstKey(), tree.lastKey()); - tree.remove(tree.lastKey()); - assertEquals(submap, tree); - } - - -} diff --git a/src/test/java/org/mapdb/BTreeMapLargeValsTest.java b/src/test/java/org/mapdb/BTreeMapLargeValsTest.java deleted file mode 100644 index ab6914ad1..000000000 --- a/src/test/java/org/mapdb/BTreeMapLargeValsTest.java +++ /dev/null @@ -1,85 +0,0 @@ - -/******************************************************************************* - * Copyright 2010 Cees De Groot, Alex Boisvert, Jan Kotek - * - * 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 - * - * http://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. - ******************************************************************************/ - -package org.mapdb; - -import org.junit.After; - -import java.util.concurrent.ConcurrentMap; - -public class BTreeMapLargeValsTest extends ConcurrentMapInterfaceTest { - - final String aa = "aiopjdqwoidjiweqpofjoiaergopieraiopgjajeiorgjoiaergiojareiogopij32-p909-iarvp9iaervijoksarfe"; - - public BTreeMapLargeValsTest() { - super(false, false, true, true, true, true,false); - } - - Engine r; - - @Override - protected void setUp() throws Exception { - r = new StoreDirect(null); - } - - - @After - public void close(){ - r.close(); - } - - @Override - protected Integer getKeyNotInPopulatedMap() throws UnsupportedOperationException { - return -100; - } - - @Override - protected String getValueNotInPopulatedMap() throws UnsupportedOperationException { - return aa+"XYZ"; - } - - @Override - protected String getSecondValueNotInPopulatedMap() throws UnsupportedOperationException { - return aa+"AAAA"; - } - - - boolean valsOutside = false; - @Override - protected ConcurrentMap makeEmptyMap() throws UnsupportedOperationException { - return new BTreeMap(r,BTreeMap.createRootRef(r,BTreeKeySerializer.BASIC, Serializer.BASIC,0), - 6,valsOutside,0, BTreeKeySerializer.BASIC,Serializer.BASIC, - 0); - - } - - public static class Outside extends BTreeMapLargeValsTest { - { - valsOutside = true; - } - } - - @Override - protected ConcurrentMap makePopulatedMap() throws UnsupportedOperationException { - ConcurrentMap map = makeEmptyMap(); - for (int i = 0; i < 100; i++){ - map.put(i, aa+"aa" + i); - } - return map; - } - -} diff --git a/src/test/java/org/mapdb/BTreeMapNavigable2Test.java b/src/test/java/org/mapdb/BTreeMapNavigable2Test.java deleted file mode 100644 index 2384056cb..000000000 --- a/src/test/java/org/mapdb/BTreeMapNavigable2Test.java +++ /dev/null @@ -1,514 +0,0 @@ -package org.mapdb; - -import junit.framework.TestCase; -import org.junit.After; - -import java.util.*; - -@SuppressWarnings({ "unchecked" }) -public class BTreeMapNavigable2Test extends TestCase -{ - NavigableMap map; - - @Override - public void setUp() throws Exception - { - map = newMap(); - map.put(1, "one"); - map.put(2, "two"); - map.put(3, "three"); - map.put(4, "four"); - - map.put(7, "seven"); - map.put(8, "eight"); - map.put(9, "nine"); - map.put(10, "ten"); - } - - - @Override - protected void tearDown() throws Exception { - map = null; - } - - protected NavigableMap newMap() { - return DBMaker.newMemoryDB().make().createTreeMap("map").make(); - } - - - public static class Outside extends BTreeMapNavigable2Test{ - @Override protected NavigableMap newMap() { - return DBMaker.newMemoryDB().make().createTreeMap("map").valuesOutsideNodesEnable().make(); - } - } - - public void testSize() - { - int i = 8; - assertEquals(map.size(), i); - while (!map.isEmpty()) - { - map.remove(map.firstKey()); - assertEquals(map.size(), --i); - } - } - - - public void testContainsKey() - { - assertTrue(map.containsKey(1)); - assertTrue(map.containsKey(2)); - assertTrue(map.containsKey(3)); - assertTrue(map.containsKey(4)); - assertFalse(map.containsKey(5)); - assertFalse(map.containsKey(6)); - assertTrue(map.containsKey(7)); - assertTrue(map.containsKey(8)); - assertTrue(map.containsKey(9)); - assertTrue(map.containsKey(10)); - - assertFalse(map.containsKey(999)); - assertFalse(map.containsKey(-1)); - } - - - public void testContainsValue() - { - assertTrue(map.containsValue("one")); - assertTrue(map.containsValue("two")); - assertTrue(map.containsValue("three")); - assertTrue(map.containsValue("four")); - assertFalse(map.containsValue("five")); - assertFalse(map.containsValue("six")); - assertTrue(map.containsValue("seven")); - assertTrue(map.containsValue("eight")); - assertTrue(map.containsValue("nine")); - assertTrue(map.containsValue("ten")); - - assertFalse(map.containsValue("aaaa")); - } - - - public void testPut() - { - assertFalse(map.containsKey(40)); - assertFalse(map.containsValue("forty")); - map.put(40, "forty"); - assertTrue(map.containsKey(40)); - assertTrue(map.containsValue("forty")); - } - - - public void testLowerEntry() - { - AbstractMap.Entry e = map.lowerEntry(4); - assertEquals(e.getKey(), (Integer)3); - } - - - public void testLowerKey() - { - Integer key = map.lowerKey(4); - assertEquals(key, (Integer)3); - } - - - public void testFloorEntry() - { - AbstractMap.Entry e = map.floorEntry(6); - assertEquals(e.getKey(), (Integer)4); - - e = map.floorEntry(7); - assertEquals(e.getKey(), (Integer)7); - } - - - public void testFloorKey() - { - Integer key = map.floorKey(6); - assertEquals(key, (Integer)4); - - key = map.floorKey(7); - assertEquals(key, (Integer)7); - } - - - public void testCeilingEntry() - { - AbstractMap.Entry e = map.ceilingEntry(6); - assertEquals(e.getKey(), (Integer)7); - - e = map.ceilingEntry(7); - assertEquals(e.getKey(), (Integer)7); - } - - - public void testCeilingKey() - { - Integer key = map.ceilingKey(6); - assertEquals(key, (Integer)7); - - key = map.ceilingKey(7); - assertEquals(key, (Integer)7); - } - - - public void testHigherEntry() - { - AbstractMap.Entry e = map.higherEntry(4); - assertEquals(e.getKey(), (Integer)7); - - e = map.higherEntry(7); - assertEquals(e.getKey(), (Integer)8); - } - - - public void testHigherKey() - { - Integer key = map.higherKey(4); - assertEquals(key, (Integer)7); - - key = map.higherKey(7); - assertEquals(key, (Integer)8); - } - - - public void testFirstEntry() - { - assertEquals( - map.firstEntry().getKey(), - (Integer) 1); - } - - - public void testLastEntry() - { - assertEquals( - map.lastEntry().getKey(), - (Integer) 10); - } - - - public void testPollFirstEntry() - { - int size0 = map.size(); - AbstractMap.Entry e = map.pollFirstEntry(); - int size1 = map.size(); - assertEquals(size0-1, size1); - - assertNull(map.get(1)); - assertEquals(e.getKey(), (Integer)1); - assertEquals(e.getValue(), "one"); - } - - - public void testPollLastEntry() - { - int size0 = map.size(); - AbstractMap.Entry e = map.pollLastEntry(); - int size1 = map.size(); - assertEquals(size0-1, size1); - - assertNull(map.get(10)); - assertEquals(e.getKey(), (Integer)10); - assertEquals(e.getValue(), "ten"); - } - - - public void testDescendingMap() - { - - NavigableMap desMap = map.descendingMap(); - Set> entrySet1 = map.entrySet(); - Set> entrySet2 = desMap.entrySet(); - AbstractMap.Entry[] arr1 = entrySet1.toArray(new AbstractMap.Entry[0]); - AbstractMap.Entry[] arr2 = entrySet2.toArray(new AbstractMap.Entry[0]); - - int size = arr1.length; - assertEquals(arr1.length, arr2.length); - for (int i = 0; i < arr1.length; i++) - { - assertEquals(arr1[i], arr2[size-1-i]); - } - } - - - public void testNavigableKeySet() - { - int size0 = map.size(); - NavigableSet keySet = map.navigableKeySet(); - int size1 = keySet.size(); - assertEquals(size0, size1); - - keySet.remove(2); - size0 = map.size(); - size1 = keySet.size(); - assertEquals(size0, size1); - assertNull(map.get(2)); - } - - - public void testDescendingKeySet() - { - Set keySet1 = map.keySet(); - Set keySet2 = map.descendingKeySet(); - - Integer[] arr1 = keySet1.toArray(new Integer[0]); - Integer[] arr2 = keySet2.toArray(new Integer[0]); - int size = arr1.length; - assertEquals(arr1.length, arr2.length); - for (int i = 0; i < size; i++) - { - assertEquals(arr1[i],arr2[size-1-i]); - } - } - - - public void testSubMap() - { - SortedMap subMap = map.subMap(3, 8); - assertNotNull(subMap.get(3)); - assertEquals(subMap.get(3), "three"); - assertEquals(subMap.get(4), "four"); - assertNull(subMap.get(5)); - assertNull(subMap.get(6)); - assertEquals(subMap.get(7), "seven"); - - assertNull(subMap.get(8)); - assertNull(subMap.get(2)); - assertNull(subMap.get(9)); - try - { - subMap.put(11,"eleven"); - fail("Inserted entry outside of submap range"); - } - catch (IllegalArgumentException e) - { - assertNull(subMap.get(11)); - } - } - - - public void testSubMap2() - { - NavigableMap subMap = map.subMap(3,true,8,false); - assertNotNull(subMap.get(3)); - assertEquals(subMap.get(3), "three"); - assertEquals(subMap.get(4), "four"); - assertNull(subMap.get(5)); - assertNull(subMap.get(6)); - assertEquals(subMap.get(7), "seven"); - - assertNull(subMap.get(8)); - assertNull(subMap.get(2)); - assertNull(subMap.get(9)); - try - { - subMap.put(11,"eleven"); - fail("Inserted entry outside of submap range"); - } - catch (IllegalArgumentException e) - { - assertNull(subMap.get(11)); - } - } - - - public void testSubMap3() - { - NavigableMap subMap = map.subMap(2, false, 8, false); - assertNotNull(subMap.get(3)); - assertEquals(subMap.get(3), "three"); - assertEquals(subMap.get(4), "four"); - assertNull(subMap.get(5)); - assertNull(subMap.get(6)); - assertEquals(subMap.get(7), "seven"); - - assertNull(subMap.get(8)); - assertNull(subMap.get(2)); - assertNull(subMap.get(9)); - try - { - subMap.put(11,"eleven"); - fail("Inserted entry outside of submap range"); - } - catch (IllegalArgumentException e) - { - assertNull(subMap.get(11)); - } - } - - - public void testSubMap4() - { - NavigableMap subMap = map.subMap(3, true, 7, true); - assertNotNull(subMap.get(3)); - assertEquals(subMap.get(3), "three"); - assertEquals(subMap.get(4), "four"); - assertNull(subMap.get(5)); - assertNull(subMap.get(6)); - assertEquals(subMap.get(7), "seven"); - - assertNull(subMap.get(8)); - assertNull(subMap.get(2)); - assertNull(subMap.get(9)); - try - { - subMap.put(11,"eleven"); - fail("Inserted entry outside of submap range"); - } - catch (IllegalArgumentException e) - { - assertNull(subMap.get(11)); - } - } - - - public void testHeadMap() - { - SortedMap subMap = map.headMap(5); - assertEquals(subMap.size(), 4); - assertNull(subMap.get(5)); - assertEquals(subMap.get(1), "one"); - try - { - subMap.put(5, "five"); - fail("Inseted data out of bounds of submap."); - } - catch (IllegalArgumentException e) - { - assertNull(subMap.get(5)); - } - } - - - public void testHeadMap2() - { - NavigableMap subMap = map.headMap(5, false); - assertEquals(subMap.size(), 4); - assertNull(subMap.get(5)); - assertEquals(subMap.get(1), "one"); - try - { - subMap.put(5, "five"); - fail("Inseted data out of bounds of submap."); - } - catch (IllegalArgumentException e) - { - assertNull(subMap.get(5)); - } - } - - - public void testHeadMap3() - { - NavigableMap subMap = map.headMap(5, true); - assertEquals(subMap.size(), 4); - assertNull(subMap.get(5)); - assertEquals(subMap.get(1), "one"); - try - { - subMap.put(5, "five"); - assertEquals(subMap.get(5), "five"); - } - catch (IllegalArgumentException e) - { - fail("It was not possible to insert a legal value in a submap."); - } - } - - - public void testHeadMap4() - { - NavigableMap subMap = map.headMap(8, true); - assertEquals(subMap.size(), 6); - assertEquals(subMap.get(8), "eight"); - assertEquals(subMap.get(1), "one"); - try - { - subMap.put(5, "five"); - assertEquals(subMap.get(5), "five"); - } - catch (IllegalArgumentException e) - { - fail("It was not possible to insert a legal value in a submap."); - } - } - - - public void testTailMap() - { - SortedMap subMap = map.tailMap(5); - assertEquals(subMap.size(), 4); - assertEquals(subMap.firstKey(), (Integer)7); - assertEquals(subMap.lastKey(), (Integer)10); - } - - - public void testTailMap2() - { - SortedMap subMap = map.tailMap(7); - assertEquals(subMap.size(), 4); - assertEquals(subMap.firstKey(), (Integer)7); - assertEquals(subMap.lastKey(), (Integer)10); - } - - - public void testTailMap3() - { - NavigableMap subMap = map.tailMap(7, false); - assertEquals(subMap.size(), 3); - assertEquals(subMap.firstKey(), (Integer)8); - assertEquals(subMap.lastKey(), (Integer)10); - } - - - public void testTailMap4() - { - NavigableMap subMap = map.tailMap(7, true); - assertEquals(subMap.size(), 4); - assertEquals(subMap.firstKey(), (Integer)7); - assertEquals(subMap.lastKey(), (Integer)10); - } - - - public void testIsEmpty() - { - assertFalse(map.isEmpty()); - map.clear(); - assertTrue(map.isEmpty()); - } - - - public void testClearSubmap() - { - NavigableMap subMap = map.subMap(7, true, 9, true); - subMap.clear(); - assertEquals(subMap.size(), 0); - assertTrue(map.size()==5); - assertNull(map.get(7)); - assertNull(map.get(8)); - assertNull(map.get(9)); - } - -// -// public void testConcurrentModification() -// { -// Set> entrySet = map.entrySet(); -// assertTrue(entrySet.size() > 0); -// try -// { -// -// for (AbstractMap.Entry e : entrySet) -// entrySet.remove(e); -// -// fail("No concurrentModificationException was thrown"); -// } -// catch (ConcurrentModificationException ex){} -// -// -// } - - - -} diff --git a/src/test/java/org/mapdb/BTreeMapNavigableSubMapExclusiveTest.java b/src/test/java/org/mapdb/BTreeMapNavigableSubMapExclusiveTest.java deleted file mode 100644 index 9993c1789..000000000 --- a/src/test/java/org/mapdb/BTreeMapNavigableSubMapExclusiveTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.mapdb; - -import java.util.NavigableMap; - -public class BTreeMapNavigableSubMapExclusiveTest extends BTreeMapNavigable2Test{ - - public static class Outside extends BTreeMapNavigableSubMapExclusiveTest{ - @Override protected NavigableMap newMap() { - return DBMaker.newMemoryDB().make().createTreeMap("map").valuesOutsideNodesEnable().make(); - } - - } - - @Override - public void setUp() throws Exception { - super.setUp(); - map.put(-1,"-one"); - map.put(0,"zero"); - map.put(11,"eleven"); - map.put(12,"twelve"); - map = map.subMap(0,false,11,false); - } - - - @Override - public void testPut(){ - //this test is not run on submaps - } -} diff --git a/src/test/java/org/mapdb/BTreeMapNavigableSubMapInclusiveTest.java b/src/test/java/org/mapdb/BTreeMapNavigableSubMapInclusiveTest.java deleted file mode 100644 index cad857a29..000000000 --- a/src/test/java/org/mapdb/BTreeMapNavigableSubMapInclusiveTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.mapdb; - -import java.util.NavigableMap; - -public class BTreeMapNavigableSubMapInclusiveTest extends BTreeMapNavigable2Test{ - - public static class Outside extends BTreeMapNavigableSubMapInclusiveTest{ - @Override protected NavigableMap newMap() { - return DBMaker.newMemoryDB().make().createTreeMap("map").valuesOutsideNodesEnable().make(); - } - } - - - @Override - public void setUp() throws Exception { - super.setUp(); - map.put(0,"zero"); - map.put(11,"eleven"); - map = map.subMap(1,true,10,true); - } - - - @Override - public void testPut(){ - //this test is not run on submaps - } -} diff --git a/src/test/java/org/mapdb/BTreeMapNavigableTest.java b/src/test/java/org/mapdb/BTreeMapNavigableTest.java deleted file mode 100644 index 727cf3245..000000000 --- a/src/test/java/org/mapdb/BTreeMapNavigableTest.java +++ /dev/null @@ -1,355 +0,0 @@ -/* -* Copyright 2012 Luc Peuvrier -* All rights reserved. -* -* This file is a part of JOAFIP. -* -* JOAFIP is free software: you can redistribute it and/or modify -* it under the terms of the GNU Lesser General Public License. -* -* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE -* Licensed under the LGPL License, Version 3, 29 June 2007 (the "LGPL License"); -* you may not use this file except in compliance with the "LGPL License" extended with here below additional permissions. -* You may obtain a copy of the "LGPL License" at -* -* http://www.gnu.org/licenses/lgpl.html -* -* Additional permissions extensions for this file: -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted under the the Apache License, Version 2.0 (the "Apache License") instead of the "LGPL License" -* and if following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holders nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* You may obtain a copy of the "Apache License" at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* JOAFIP is distributed in the hope that it will be useful, but -* 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. -*/ -package org.mapdb; - -import junit.framework.TestCase; - -import java.util.*; -import java.util.Map.Entry; - -/** - * to test {@link java.util.NavigableMap} implementation - * - * @author luc peuvrier - * - */ -public class BTreeMapNavigableTest extends TestCase { - - private static final String MUST_NOT_CONTAINS_KD = "must not contains 'kd'"; - - private static final String MUST_NOT_CONTAINS_KA = "must not contains 'ka'"; - - private static final String BAD_FIRST_ENTRY_KEY = "bad first entry key"; - - private static final String MUST_NOT_BE_EMPTY = "must not be empty"; - - private static final String BAD_SIZE = "bad size"; - - private static final String MUST_CONTAINS_KC = "must contains 'kc'"; - - private static final String MUST_CONTAINS_KB = "must contains 'kb'"; - - private static final String MUST_CONTAINS_KA = "must contains 'ka'"; - - private NavigableMap navigableMap; - - - protected NavigableMap newMap() { - return DBMaker.newMemoryDB().make().createTreeMap("map").make(); - } - - public static class Outside extends BTreeMapNavigableTest{ - @Override protected NavigableMap newMap() { - return DBMaker.newMemoryDB().make().createTreeMap("map").valuesOutsideNodesEnable().make(); - } - } - - - @Override - protected void setUp() throws Exception { - navigableMap = newMap(); - } - - @Override - protected void tearDown() throws Exception { - ((BTreeMap)navigableMap).engine.close(); - } - - public void testLowerEntry() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - final Entry lowerEntry = navigableMap.lowerEntry("kb"); - assertEquals("bad lower entry value", "xx", lowerEntry.getValue()); - assertEquals("bad lower entry key", "ka", lowerEntry.getKey()); - } - - public void testLowerKey() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - assertEquals("bad lower key", "ka", navigableMap.lowerKey("kb")); - } - - public void testFloorEntry() { - navigableMap.put("ka", "xx"); - navigableMap.put("kc", "aa"); - navigableMap.put("kd", "zz"); - Entry floorEntry = navigableMap.floorEntry("ka"); - assertEquals("bad floor entry value", "xx", floorEntry.getValue()); - assertEquals("bad floor entry key", "ka", floorEntry.getKey()); - floorEntry = navigableMap.floorEntry("kb"); - assertEquals("bad floor entry value", "xx", floorEntry.getValue()); - assertEquals("bad floor entry key", "ka", floorEntry.getKey()); - } - - public void testFloorKey() { - navigableMap.put("ka", "xx"); - navigableMap.put("kc", "aa"); - navigableMap.put("kd", "zz"); - assertEquals("bad floor key", "ka", navigableMap.floorKey("ka")); - assertEquals("bad floor key", "ka", navigableMap.floorKey("kb")); - } - - public void testCeilingEntry() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kd", "zz"); - Entry ceilingEntry = navigableMap.ceilingEntry("kd"); - assertEquals("bad ceiling entry value", "zz", ceilingEntry.getValue()); - assertEquals("bad ceiling entry key", "kd", ceilingEntry.getKey()); - ceilingEntry = navigableMap.ceilingEntry("kc"); - assertEquals("bad ceiling entry value", "zz", ceilingEntry.getValue()); - assertEquals("bad ceiling entry key", "kd", ceilingEntry.getKey()); - } - - public void testCeilingKey() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kd", "zz"); - assertEquals("bad ceiling key", "kd", navigableMap.ceilingKey("kd")); - assertEquals("bad ceiling key", "kd", navigableMap.ceilingKey("kc")); - } - - public void testHigherEntry() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - final Entry higherEntry = navigableMap - .higherEntry("kb"); - assertEquals("bad higher entry value", "zz", higherEntry.getValue()); - assertEquals("bad higher entry key", "kc", higherEntry.getKey()); - } - - public void testHigherKey() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - assertEquals("bad higher key", "kc", navigableMap.higherKey("kb")); - } - - public void testFirstEntry() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - final Entry firstEntry = navigableMap.firstEntry(); - assertEquals("bad first entry value", "xx", firstEntry.getValue()); - assertEquals(BAD_FIRST_ENTRY_KEY, "ka", firstEntry.getKey()); - } - - public void testLastEntry() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - final Entry lastEntry = navigableMap.lastEntry(); - assertEquals("bad last entry value", "zz", lastEntry.getValue()); - assertEquals("bad last entry key", "kc", lastEntry.getKey()); - } - - public void testPollFirstEntry() { - assertNull("must not have first entry", navigableMap.pollFirstEntry()); - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - assertEquals("must have 3 entries", 3, navigableMap.size()); - final Entry firstEntry = navigableMap.pollFirstEntry(); - assertNotNull("must have first entry", firstEntry); - assertEquals("bad first entry value", "xx", firstEntry.getValue()); - assertEquals(BAD_FIRST_ENTRY_KEY, "ka", firstEntry.getKey()); - assertEquals("must have 2 entries", 2, navigableMap.size()); - } - - public void testPollLastEntry() { - assertNull("must not have last entry", navigableMap.pollLastEntry()); - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - assertEquals("must have 3 entries", 3, navigableMap.size()); - final Entry lastEntry = navigableMap.pollLastEntry(); - assertNotNull("must have last entry", lastEntry); - assertEquals("bad last entry value", "zz", lastEntry.getValue()); - assertEquals("bad last entry key", "kc", lastEntry.getKey()); - assertEquals("must have 2 entries", 2, navigableMap.size()); - } - - public void testDescendingMap() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - final NavigableMap descendingMap = navigableMap - .descendingMap(); - - assertEquals(BAD_SIZE, 3, descendingMap.size()); - assertFalse(MUST_NOT_BE_EMPTY, descendingMap.isEmpty()); - - final Entry firstEntry = descendingMap.firstEntry(); - assertEquals("bad first entry value", "zz", firstEntry.getValue()); - assertEquals(BAD_FIRST_ENTRY_KEY, "kc", firstEntry.getKey()); - - final Entry lastEntry = descendingMap.lastEntry(); - assertEquals("bad last entry value", "xx", lastEntry.getValue()); - assertEquals("bad last entry key", "ka", lastEntry.getKey()); - - final Set> entrySet = descendingMap.entrySet(); - final Iterator> iterator = entrySet.iterator(); - assertTrue("must have first entry", iterator.hasNext()); - assertEquals(BAD_FIRST_ENTRY_KEY, "kc", iterator.next().getKey()); - assertTrue("must have second entry", iterator.hasNext()); - assertEquals("bad second entry key", "kb", iterator.next().getKey()); - assertTrue("must have third entry", iterator.hasNext()); - assertEquals("bad third entry key", "ka", iterator.next().getKey()); - assertFalse("must not have fourth entry", iterator.hasNext()); - - descendingMap.remove("kb"); - assertEquals(BAD_SIZE, 2, descendingMap.size()); - assertFalse(MUST_NOT_BE_EMPTY, descendingMap.isEmpty()); - - assertEquals(BAD_SIZE, 2, navigableMap.size()); - assertFalse(MUST_NOT_BE_EMPTY, navigableMap.isEmpty()); - assertTrue("must contains key 'ka'", navigableMap.containsKey("ka")); - assertFalse("must not contains key 'kb'", navigableMap - .containsKey("kb")); - assertTrue("must contains key 'kc'", navigableMap.containsKey("kc")); - } - - public void testNavigableKeySet() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - final NavigableSet navigableSet = navigableMap - .navigableKeySet(); - assertEquals("bad first element", "ka", navigableSet.first()); - assertEquals("bad last element", "kc", navigableSet.last()); - assertTrue(MUST_CONTAINS_KA, navigableSet.contains("ka")); - assertTrue(MUST_CONTAINS_KB, navigableSet.contains("kb")); - assertTrue(MUST_CONTAINS_KC, navigableSet.contains("kc")); - - navigableSet.remove("kb"); - assertEquals(BAD_SIZE, 2, navigableMap.size()); - assertFalse(MUST_NOT_BE_EMPTY, navigableMap.isEmpty()); - assertTrue("must contains key 'ka'", navigableMap.containsKey("ka")); - assertFalse("must not contains key 'kb'", navigableMap - .containsKey("kb")); - assertTrue("must contains key 'kc'", navigableMap.containsKey("kc")); - } - - public void testDescendingKeySet() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - final NavigableSet navigableSet = navigableMap - .descendingKeySet(); - assertEquals("bad first element", "kc", navigableSet.first()); - assertEquals("bad last element", "ka", navigableSet.last()); - assertTrue(MUST_CONTAINS_KA, navigableSet.contains("ka")); - assertTrue(MUST_CONTAINS_KB, navigableSet.contains("kb")); - assertTrue(MUST_CONTAINS_KC, navigableSet.contains("kc")); - - navigableSet.remove("kb"); - assertEquals(BAD_SIZE, 2, navigableMap.size()); - assertFalse(MUST_NOT_BE_EMPTY, navigableMap.isEmpty()); - assertTrue("must contains key 'ka'", navigableMap.containsKey("ka")); - assertFalse("must not contains key 'kb'", navigableMap - .containsKey("kb")); - assertTrue("must contains key 'kc'", navigableMap.containsKey("kc")); - } - - public void testSubMap() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - navigableMap.put("kd", "uu"); - - SortedMap sortedMap = navigableMap.subMap("kb", "kd"); - assertFalse(MUST_NOT_CONTAINS_KA, sortedMap.containsKey("ka")); - assertTrue(MUST_CONTAINS_KB, sortedMap.containsKey("kb")); - assertTrue(MUST_CONTAINS_KC, sortedMap.containsKey("kc")); - assertFalse(MUST_NOT_CONTAINS_KD, sortedMap.containsKey("kd")); - - sortedMap = navigableMap.subMap("ka", false, "kc", true); - assertFalse(MUST_NOT_CONTAINS_KA, sortedMap.containsKey("ka")); - assertTrue(MUST_CONTAINS_KB, sortedMap.containsKey("kb")); - assertTrue(MUST_CONTAINS_KC, sortedMap.containsKey("kc")); - assertFalse(MUST_NOT_CONTAINS_KD, sortedMap.containsKey("kd")); - } - - public void testHeadMap() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - navigableMap.put("kd", "uu"); - - SortedMap sortedMap = navigableMap.headMap("kc"); - assertTrue(MUST_CONTAINS_KA, sortedMap.containsKey("ka")); - assertTrue(MUST_CONTAINS_KB, sortedMap.containsKey("kb")); - assertFalse("must not contains 'kc'", sortedMap.containsKey("kc")); - assertFalse(MUST_NOT_CONTAINS_KD, sortedMap.containsKey("kd")); - - sortedMap = navigableMap.headMap("kb", true); - assertTrue(MUST_CONTAINS_KA, sortedMap.containsKey("ka")); - assertTrue(MUST_CONTAINS_KB, sortedMap.containsKey("kb")); - assertFalse("must not contains 'kc'", sortedMap.containsKey("kc")); - assertFalse(MUST_NOT_CONTAINS_KD, sortedMap.containsKey("kd")); - } - - public void testTailMap() { - navigableMap.put("ka", "xx"); - navigableMap.put("kb", "aa"); - navigableMap.put("kc", "zz"); - navigableMap.put("kd", "uu"); - - SortedMap sortedMap = navigableMap.tailMap("kc"); - assertFalse(MUST_NOT_CONTAINS_KA, sortedMap.containsKey("ka")); - assertFalse("must not contains 'kb'", sortedMap.containsKey("kb")); - assertTrue(MUST_CONTAINS_KC, sortedMap.containsKey("kc")); - assertTrue("must contains 'kd'", sortedMap.containsKey("kd")); - - sortedMap = navigableMap.tailMap("kb", false); - assertFalse(MUST_NOT_CONTAINS_KA, sortedMap.containsKey("ka")); - assertFalse("must not contains 'kb'", sortedMap.containsKey("kb")); - assertTrue(MUST_CONTAINS_KC, sortedMap.containsKey("kc")); - assertTrue("must contains 'kd'", sortedMap.containsKey("kd")); - } -} diff --git a/src/test/java/org/mapdb/BTreeMapParTest.java b/src/test/java/org/mapdb/BTreeMapParTest.java deleted file mode 100644 index 24e2dc063..000000000 --- a/src/test/java/org/mapdb/BTreeMapParTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertEquals; - -public class BTreeMapParTest { - - - final int threadNum = 6; - final int max = (int) 1e6; - - @Test - public void parInsert() throws InterruptedException { - - ExecutorService s = Executors.newCachedThreadPool(); - final ConcurrentMap m = DBMaker.newMemoryDB().transactionDisable().make() - .createTreeMap("test") - .valueSerializer(Serializer.LONG) - .makeLongMap(); - - long t = System.currentTimeMillis(); - - for(int j=0;j populatedSet(int n) { - NavigableSet q = - newNavigableSet(); - assertTrue(q.isEmpty()); - - for (int i = n-1; i >= 0; i-=2) - assertTrue(q.add(new Integer(i))); - for (int i = (n & 1); i < n; i+=2) - assertTrue(q.add(new Integer(i))); - assertTrue(q.add(new Integer(-n))); - assertTrue(q.add(new Integer(n))); - NavigableSet s = q.subSet(new Integer(0), true, new Integer(n), false); - assertFalse(s.isEmpty()); - assertEquals(n, s.size()); - return s; - } - - protected NavigableSet newNavigableSet() { - return DBMaker.newMemoryDB().transactionDisable() - .cacheDisable() - .make().getTreeSet("test"); - } - - /** - * Returns a new set of first 5 ints. - */ - private NavigableSet set5() { - NavigableSet q = newNavigableSet(); - assertTrue(q.isEmpty()); - q.add(one); - q.add(two); - q.add(three); - q.add(four); - q.add(five); - q.add(zero); - q.add(seven); - NavigableSet s = q.subSet(one, true, seven, false); - assertEquals(5, s.size()); - return s; - } - - - private NavigableSet set0() { - NavigableSet set = newNavigableSet(); - assertTrue(set.isEmpty()); - return set.tailSet(m1, true); - } - - private NavigableSet dset0() { - NavigableSet set = newNavigableSet(); - assertTrue(set.isEmpty()); - return set; - } - - /** - * A new set has unbounded capacity - */ - public void testConstructor1() { - assertEquals(0, set0().size()); - } - - /** - * isEmpty is true before add, false after - */ - public void testEmpty() { - NavigableSet q = set0(); - assertTrue(q.isEmpty()); - q.add(new Integer(1)); - assertFalse(q.isEmpty()); - q.add(new Integer(2)); - q.pollFirst(); - q.pollFirst(); - assertTrue(q.isEmpty()); - } - - - - /** - * add(null) throws NPE - */ - public void testAddNull() { - try { - NavigableSet q = set0(); - q.add(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Add of comparable element succeeds - */ - public void testAdd() { - NavigableSet q = set0(); - assertTrue(q.add(six)); - } - - /** - * Add of duplicate element fails - */ - public void testAddDup() { - NavigableSet q = set0(); - assertTrue(q.add(six)); - assertFalse(q.add(six)); - } - - /** - * Add of non-Comparable throws CCE - */ - public void testAddNonComparable() { - try { - NavigableSet q = set0(); - q.add(new Object()); - q.add(new Object()); - q.add(new Object()); - shouldThrow(); - } catch (ClassCastException success) {} - } - - /** - * addAll(null) throws NPE - */ - public void testAddAll1() { - try { - NavigableSet q = set0(); - q.addAll(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with null elements throws NPE - */ - public void testAddAll2() { - try { - NavigableSet q = set0(); - Integer[] ints = new Integer[SIZE]; - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with any null elements throws NPE after - * possibly adding some elements - */ - public void testAddAll3() { - try { - NavigableSet q = set0(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i+SIZE); - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Set contains all elements of successful addAll - */ - public void testAddAll5() { - Integer[] empty = new Integer[0]; - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE; ++i) - ints[i] = new Integer(SIZE-1- i); - NavigableSet q = set0(); - assertFalse(q.addAll(Arrays.asList(empty))); - assertTrue(q.addAll(Arrays.asList(ints))); - for (int i = 0; i < SIZE; ++i) - assertEquals(new Integer(i), q.pollFirst()); - } - - /** - * poll succeeds unless empty - */ - public void testPoll() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertEquals(i, q.pollFirst()); - } - assertNull(q.pollFirst()); - } - - /** - * remove(x) removes x and returns true if present - */ - public void testRemoveElement() { - NavigableSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { - assertTrue(q.contains(i)); - assertTrue(q.remove(i)); - assertFalse(q.contains(i)); - assertTrue(q.contains(i-1)); - } - for (int i = 0; i < SIZE; i+=2) { - assertTrue(q.contains(i)); - assertTrue(q.remove(i)); - assertFalse(q.contains(i)); - assertFalse(q.remove(i+1)); - assertFalse(q.contains(i+1)); - } - assertTrue(q.isEmpty()); - } - - /** - * contains(x) reports true when elements added but not yet removed - */ - public void testContains() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.contains(new Integer(i))); - q.pollFirst(); - assertFalse(q.contains(new Integer(i))); - } - } - - - - /** - * containsAll(c) is true when c contains a subset of elements - */ - public void testContainsAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = set0(); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.containsAll(p)); - assertFalse(p.containsAll(q)); - p.add(new Integer(i)); - } - assertTrue(p.containsAll(q)); - } - - /** - * retainAll(c) retains only those elements of c and reports true if changed - */ - public void testRetainAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - boolean changed = q.retainAll(p); - if (i == 0) - assertFalse(changed); - else - assertTrue(changed); - - assertTrue(q.containsAll(p)); - assertEquals(SIZE-i, q.size()); - p.pollFirst(); - } - } - - /** - * removeAll(c) removes only those elements of c and reports true if changed - */ - public void testRemoveAll() { - for (int i = 1; i < SIZE; ++i) { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(i); - assertTrue(q.removeAll(p)); - assertEquals(SIZE-i, q.size()); - for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); - } - } - } - - /** - * lower returns preceding element - */ - public void testLower() { - NavigableSet q = set5(); - Object e1 = q.lower(three); - assertEquals(two, e1); - - Object e2 = q.lower(six); - assertEquals(five, e2); - - Object e3 = q.lower(one); - assertNull(e3); - - Object e4 = q.lower(zero); - assertNull(e4); - } - - /** - * higher returns next element - */ - public void testHigher() { - NavigableSet q = set5(); - Object e1 = q.higher(three); - assertEquals(four, e1); - - Object e2 = q.higher(zero); - assertEquals(one, e2); - - Object e3 = q.higher(five); - assertNull(e3); - - Object e4 = q.higher(six); - assertNull(e4); - } - - /** - * floor returns preceding element - */ - public void testFloor() { - NavigableSet q = set5(); - Object e1 = q.floor(three); - assertEquals(three, e1); - - Object e2 = q.floor(six); - assertEquals(five, e2); - - Object e3 = q.floor(one); - assertEquals(one, e3); - - Object e4 = q.floor(zero); - assertNull(e4); - } - - /** - * ceiling returns next element - */ - public void testCeiling() { - NavigableSet q = set5(); - Object e1 = q.ceiling(three); - assertEquals(three, e1); - - Object e2 = q.ceiling(zero); - assertEquals(one, e2); - - Object e3 = q.ceiling(five); - assertEquals(five, e3); - - Object e4 = q.ceiling(six); - assertNull(e4); - } - - /** - * toArray contains all elements in sorted order - */ - public void testToArray() { - NavigableSet q = populatedSet(SIZE); - Object[] o = q.toArray(); - for (int i = 0; i < o.length; i++) - assertSame(o[i], q.pollFirst()); - } - - /** - * toArray(a) contains all elements in sorted order - */ - public void testToArray2() { - NavigableSet q = populatedSet(SIZE); - Integer[] ints = new Integer[SIZE]; - Integer[] array = q.toArray(ints); - assertSame(ints, array); - for (int i = 0; i < ints.length; i++) - assertSame(ints[i], q.pollFirst()); - } - - /** - * iterator iterates through all elements - */ - public void testIterator() { - NavigableSet q = populatedSet(SIZE); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(i, SIZE); - } - - /** - * iterator of empty set has no elements - */ - public void testEmptyIterator() { - NavigableSet q = set0(); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(0, i); - } - - /** - * iterator.remove removes current element - */ - public void testIteratorRemove() { - final NavigableSet q = set0(); - q.add(new Integer(2)); - q.add(new Integer(1)); - q.add(new Integer(3)); - - Iterator it = q.iterator(); - it.next(); - it.remove(); - - it = q.iterator(); - assertEquals(it.next(), new Integer(2)); - assertEquals(it.next(), new Integer(3)); - assertFalse(it.hasNext()); - } - - /** - * toString contains toStrings of elements - */ - public void testToString() { - NavigableSet q = populatedSet(SIZE); - String s = q.toString(); - for (int i = 0; i < SIZE; ++i) { - assertTrue(s.contains(String.valueOf(i))); - } - } -// -// /** -// * A deserialized serialized set has same elements -// */ -// public void testSerialization() throws Exception { -// NavigableSet x = populatedSet(SIZE); -// NavigableSet y = serialClone(x); -// -// assertTrue(x != y); -// assertEquals(x.size(), y.size()); -// assertEquals(x, y); -// assertEquals(y, x); -// while (!x.isEmpty()) { -// assertFalse(y.isEmpty()); -// assertEquals(x.pollFirst(), y.pollFirst()); -// } -// assertTrue(y.isEmpty()); -// } - - /** - * subSet returns set with keys in requested range - */ - public void testSubSetContents() { - NavigableSet set = set5(); - SortedSet sm = set.subSet(two, four); - assertEquals(two, sm.first()); - assertEquals(three, sm.last()); - assertEquals(2, sm.size()); - assertFalse(sm.contains(one)); - assertTrue(sm.contains(two)); - assertTrue(sm.contains(three)); - assertFalse(sm.contains(four)); - assertFalse(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - assertFalse(i.hasNext()); - Iterator j = sm.iterator(); - j.next(); - j.remove(); - assertFalse(set.contains(two)); - assertEquals(4, set.size()); - assertEquals(1, sm.size()); - assertEquals(three, sm.first()); - assertEquals(three, sm.last()); - assertTrue(sm.remove(three)); - assertTrue(sm.isEmpty()); - assertEquals(3, set.size()); - } - - public void testSubSetContents2() { - NavigableSet set = set5(); - SortedSet sm = set.subSet(two, three); - assertEquals(1, sm.size()); - assertEquals(two, sm.first()); - assertEquals(two, sm.last()); - assertFalse(sm.contains(one)); - assertTrue(sm.contains(two)); - assertFalse(sm.contains(three)); - assertFalse(sm.contains(four)); - assertFalse(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - assertFalse(i.hasNext()); - Iterator j = sm.iterator(); - j.next(); - j.remove(); - assertFalse(set.contains(two)); - assertEquals(4, set.size()); - assertEquals(0, sm.size()); - assertTrue(sm.isEmpty()); - assertFalse(sm.remove(three)); - assertEquals(4, set.size()); - } - - /** - * headSet returns set with keys in requested range - */ - public void testHeadSetContents() { - NavigableSet set = set5(); - SortedSet sm = set.headSet(four); - assertTrue(sm.contains(one)); - assertTrue(sm.contains(two)); - assertTrue(sm.contains(three)); - assertFalse(sm.contains(four)); - assertFalse(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(one, k); - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - assertFalse(i.hasNext()); - sm.clear(); - assertTrue(sm.isEmpty()); - assertEquals(2, set.size()); - assertEquals(four, set.first()); - } - - /** - * tailSet returns set with keys in requested range - */ - public void testTailSetContents() { - NavigableSet set = set5(); - SortedSet sm = set.tailSet(two); - assertFalse(sm.contains(one)); - assertTrue(sm.contains(two)); - assertTrue(sm.contains(three)); - assertTrue(sm.contains(four)); - assertTrue(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - k = (Integer)(i.next()); - assertEquals(four, k); - k = (Integer)(i.next()); - assertEquals(five, k); - assertFalse(i.hasNext()); - - SortedSet ssm = sm.tailSet(four); - assertEquals(four, ssm.first()); - assertEquals(five, ssm.last()); - assertTrue(ssm.remove(four)); - assertEquals(1, ssm.size()); - assertEquals(3, sm.size()); - assertEquals(4, set.size()); - } - -// /** -// * size changes when elements added and removed -// */ -// public void testDescendingSize() { -// NavigableSet q = populatedSet(SIZE); -// for (int i = 0; i < SIZE; ++i) { -// assertEquals(SIZE-i, q.size()); -// q.pollFirst(); -// } -// for (int i = 0; i < SIZE; ++i) { -// assertEquals(i, q.size()); -// q.add(new Integer(i)); -// } -// } - - /** - * add(null) throws NPE - */ - public void testDescendingAddNull() { - try { - NavigableSet q = dset0(); - q.add(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Add of comparable element succeeds - */ - public void testDescendingAdd() { - NavigableSet q = dset0(); - assertTrue(q.add(m6)); - } - - /** - * Add of duplicate element fails - */ - public void testDescendingAddDup() { - NavigableSet q = dset0(); - assertTrue(q.add(m6)); - assertFalse(q.add(m6)); - } - - /** - * Add of non-Comparable throws CCE - */ - public void testDescendingAddNonComparable() { - try { - NavigableSet q = dset0(); - q.add(new Object()); - q.add(new Object()); - q.add(new Object()); - shouldThrow(); - } catch (ClassCastException success) {} - } - - /** - * addAll(null) throws NPE - */ - public void testDescendingAddAll1() { - try { - NavigableSet q = dset0(); - q.addAll(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with null elements throws NPE - */ - public void testDescendingAddAll2() { - try { - NavigableSet q = dset0(); - Integer[] ints = new Integer[SIZE]; - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with any null elements throws NPE after - * possibly adding some elements - */ - public void testDescendingAddAll3() { - try { - NavigableSet q = dset0(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i+SIZE); - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Set contains all elements of successful addAll - */ - public void testDescendingAddAll5() { - Integer[] empty = new Integer[0]; - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE; ++i) - ints[i] = new Integer(SIZE-1- i); - NavigableSet q = dset0(); - assertFalse(q.addAll(Arrays.asList(empty))); - assertTrue(q.addAll(Arrays.asList(ints))); - for (int i = 0; i < SIZE; ++i) - assertEquals(new Integer(i), q.pollFirst()); - } - - /** - * poll succeeds unless empty - */ - public void testDescendingPoll() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertEquals(i, q.pollFirst()); - } - assertNull(q.pollFirst()); - } - - /** - * remove(x) removes x and returns true if present - */ - public void testDescendingRemoveElement() { - NavigableSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { - assertTrue(q.remove(new Integer(i))); - } - for (int i = 0; i < SIZE; i+=2) { - assertTrue(q.remove(new Integer(i))); - assertFalse(q.remove(new Integer(i+1))); - } - assertTrue(q.isEmpty()); - } - - /** - * contains(x) reports true when elements added but not yet removed - */ - public void testDescendingContains() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.contains(new Integer(i))); - q.pollFirst(); - assertFalse(q.contains(new Integer(i))); - } - } - - /** - * containsAll(c) is true when c contains a subset of elements - */ - public void testDescendingContainsAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = dset0(); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.containsAll(p)); - assertFalse(p.containsAll(q)); - p.add(new Integer(i)); - } - assertTrue(p.containsAll(q)); - } - - /** - * retainAll(c) retains only those elements of c and reports true if changed - */ - public void testDescendingRetainAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - boolean changed = q.retainAll(p); - if (i == 0) - assertFalse(changed); - else - assertTrue(changed); - - assertTrue(q.containsAll(p)); - assertEquals(SIZE-i, q.size()); - p.pollFirst(); - } - } - - /** - * removeAll(c) removes only those elements of c and reports true if changed - */ - public void testDescendingRemoveAll() { - for (int i = 1; i < SIZE; ++i) { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(i); - assertTrue(q.removeAll(p)); - assertEquals(SIZE-i, q.size()); - for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); - } - } - } - - /** - * toArray contains all elements - */ - public void testDescendingToArray() { - NavigableSet q = populatedSet(SIZE); - Object[] o = q.toArray(); - Arrays.sort(o); - for (int i = 0; i < o.length; i++) - assertEquals(o[i], q.pollFirst()); - } - - /** - * toArray(a) contains all elements - */ - public void testDescendingToArray2() { - NavigableSet q = populatedSet(SIZE); - Integer[] ints = new Integer[SIZE]; - assertSame(ints, q.toArray(ints)); - Arrays.sort(ints); - for (int i = 0; i < ints.length; i++) - assertEquals(ints[i], q.pollFirst()); - } - - /** - * iterator iterates through all elements - */ - public void testDescendingIterator() { - NavigableSet q = populatedSet(SIZE); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(i, SIZE); - } - - /** - * iterator of empty set has no elements - */ - public void testDescendingEmptyIterator() { - NavigableSet q = dset0(); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(0, i); - } - - /** - * iterator.remove removes current element - */ - public void testDescendingIteratorRemove() { - final NavigableSet q = dset0(); - q.add(new Integer(2)); - q.add(new Integer(1)); - q.add(new Integer(3)); - - Iterator it = q.iterator(); - it.next(); - it.remove(); - - it = q.iterator(); - assertEquals(it.next(), new Integer(2)); - assertEquals(it.next(), new Integer(3)); - assertFalse(it.hasNext()); - } - - /** - * toString contains toStrings of elements - */ - public void testDescendingToString() { - NavigableSet q = populatedSet(SIZE); - String s = q.toString(); - for (int i = 0; i < SIZE; ++i) { - assertTrue(s.contains(String.valueOf(i))); - } - } - -// /** -// * A deserialized serialized set has same elements -// */ -// public void testDescendingSerialization() throws Exception { -// NavigableSet x = dset5(); -// NavigableSet y = serialClone(x); -// -// assertTrue(x != y); -// assertEquals(x.size(), y.size()); -// assertEquals(x, y); -// assertEquals(y, x); -// while (!x.isEmpty()) { -// assertFalse(y.isEmpty()); -// assertEquals(x.pollFirst(), y.pollFirst()); -// } -// assertTrue(y.isEmpty()); -// } - -} diff --git a/src/test/java/org/mapdb/BTreeMapTest.java b/src/test/java/org/mapdb/BTreeMapTest.java deleted file mode 100644 index 53c5d7f6f..000000000 --- a/src/test/java/org/mapdb/BTreeMapTest.java +++ /dev/null @@ -1,654 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.concurrent.ConcurrentNavigableMap; -import java.util.concurrent.atomic.AtomicInteger; - -import static org.junit.Assert.*; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class BTreeMapTest{ - - Engine engine; - - - BTreeMap m; - - boolean valsOutside = false; - - @Before public void init(){ - engine = new StoreDirect(null); - m = new BTreeMap(engine,BTreeMap.createRootRef(engine,BTreeKeySerializer.BASIC,Serializer.BASIC,0), - 6,valsOutside,0, BTreeKeySerializer.BASIC,Serializer.BASIC, - 0);; - } - - @After - public void close(){ - engine.close(); - } - - - public static class Outside extends BTreeMapTest{ - { - valsOutside=true; - } - } - - @Test public void test_leaf_node_serialization() throws IOException { - - if(valsOutside) - return; - - BTreeMap.LeafNode n = new BTreeMap.LeafNode( - new Object[]{1,2,3}, - true,true,false, - new Object[]{1,2,3}, 0); - BTreeMap.LeafNode n2 = (BTreeMap.LeafNode) UtilsTest.clone(n, m.nodeSerializer); - assertArrayEquals(nodeKeysToArray(n), nodeKeysToArray(n2)); - assertEquals(n.next, n2.next); - } - - - @Test public void test_dir_node_serialization() throws IOException { - - - BTreeMap.DirNode n = new BTreeMap.DirNode( - new Object[]{1,2,3}, - false,true,false, - new long[]{4,5,6,0}); - BTreeMap.DirNode n2 = (BTreeMap.DirNode) UtilsTest.clone(n, m.nodeSerializer); - - assertArrayEquals(nodeKeysToArray(n), nodeKeysToArray(n2)); - assertArrayEquals(n.child, n2.child); - } - - @Test public void test_find_children(){ - long[] child = new long[8]; - for(int i=0;i map = DBMaker - .newMemoryDB() - .make().getTreeMap("test"); - - for (int i = 0; i < 50000; i++) { - map.put(i, new String[5]); - - } - - - for (int i = 0; i < 50000; i=i+1000) { - assertArrayEquals(new String[5], map.get(i)); - assertTrue(map.get(i).toString().contains("[Ljava.lang.String")); - } - - - } - - - - @Test public void floorTestFill() { - - m.put(1, "val1"); - m.put(2, "val2"); - m.put(5, "val3"); - - assertEquals(5,m.floorKey(5)); - assertEquals(1,m.floorKey(1)); - assertEquals(2,m.floorKey(2)); - assertEquals(2,m.floorKey(3)); - assertEquals(2,m.floorKey(4)); - assertEquals(5,m.floorKey(5)); - assertEquals(5,m.floorKey(6)); - } - - @Test public void submapToString() { - - - for (int i = 0; i < 20; i++) { - m.put(i, "aa"+i); - - } - - Map submap = m.subMap(10, true, 13, true); - assertEquals("{10=aa10, 11=aa11, 12=aa12, 13=aa13}",submap.toString()); - } - - @Test public void findSmaller(){ - - - for(int i=0;i<10000; i+=3){ - m.put(i, "aa"+i); - } - - for(int i=0;i<10000; i+=1){ - Integer s = i - i%3; - Map.Entry e = m.findSmaller(i,true); - assertEquals(s,e!=null?e.getKey():null); - } - - assertEquals(9999, m.findSmaller(100000,true).getKey()); - - assertNull(m.findSmaller(0,false)); - for(int i=1;i<10000; i+=1){ - Integer s = i - i%3; - if(s==i) s-=3; - Map.Entry e = m.findSmaller(i,false); - assertEquals(s,e!=null?e.getKey():null); - } - assertEquals(9999, m.findSmaller(100000,false).getKey()); - - } - - @Test public void NoSuchElem_After_Clear(){ -// bug reported by : Lazaros Tsochatzidis -// But after clearing the tree using: -// -// public void Delete() { -// db.getTreeMap("Names").clear(); -// db.compact(); -// } -// -// every next call of getLastKey() leads to the exception "NoSuchElement". Not -// only the first one... - - DB db = DBMaker.newTempFileDB().transactionDisable().make(); - NavigableMap m = db.getTreeMap("name"); - try{ - m.lastKey(); - fail(); - }catch(NoSuchElementException e){} - m.put("aa","aa"); - assertEquals("aa",m.lastKey()); - m.put("bb","bb"); - assertEquals("bb",m.lastKey()); - db.getTreeMap("name").clear(); - db.compact(); - try{ - Object key=m.lastKey(); - fail(key.toString()); - }catch(NoSuchElementException e){} - m.put("aa","aa"); - assertEquals("aa",m.lastKey()); - m.put("bb","bb"); - assertEquals("bb",m.lastKey()); - } - - @Test public void mod_listener_lock(){ - DB db = DBMaker.newMemoryDB().make(); - final BTreeMap m = db.getTreeMap("name"); - - final long rootRecid = db.getEngine().get(m.rootRecidRef, Serializer.LONG); - final AtomicInteger counter = new AtomicInteger(); - - m.modificationListenerAdd(new Bind.MapListener() { - @Override - public void update(Object key, Object oldVal, Object newVal) { - assertTrue(m.nodeLocks.get(rootRecid) == Thread.currentThread()); - assertEquals(1, m.nodeLocks.size()); - counter.incrementAndGet(); - } - }); - - - m.put("aa","aa"); - m.put("aa", "bb"); - m.remove("aa"); - - - m.put("aa","aa"); - m.remove("aa","aa"); - m.putIfAbsent("aa","bb"); - m.replace("aa","bb","cc"); - m.replace("aa","cc"); - - assertEquals(8, counter.get()); - } - - - @Test public void concurrent_last_key(){ - DB db = DBMaker.newMemoryDB().make(); - final BTreeMap m = db.getTreeMap("name"); - - //fill - final int c = 1000000; - for(int i=0;i<=c;i++){ - m.put(i,i); - } - - Thread t = new Thread(){ - @Override - public void run() { - for(int i=c;i>=0;i--){ - m.remove(i); - } - } - }; - t.run(); - while(t.isAlive()){ - assertNotNull(m.lastKey()); - } - } - - @Test public void concurrent_first_key(){ - DB db = DBMaker.newMemoryDB().make(); - final BTreeMap m = db.getTreeMap("name"); - - //fill - final int c = 1000000; - for(int i=0;i<=c;i++){ - m.put(i,i); - } - - Thread t = new Thread(){ - @Override - public void run() { - for(int i=0;i<=c;i++){ - m.remove(c); - } - } - }; - t.run(); - while(t.isAlive()){ - assertNotNull(m.firstKey()); - } - } - - @Test public void WriteDBInt_lastKey() { - int numberOfRecords = 1000; - - /** Creates connections to MapDB */ - DB db1 = DBMaker.newMemoryDB().make(); - - - /** Creates maps */ - ConcurrentNavigableMap map1 = db1.getTreeMap("column1"); - - /** Inserts initial values in maps */ - for (int i = 0; i < numberOfRecords; i++) { - map1.put(i, i); - } - - - assertEquals((Object) (numberOfRecords - 1), map1.lastKey()); - - map1.clear(); - - /** Inserts some values in maps */ - for (int i = 0; i < 10; i++) { - map1.put(i, i); - } - - assertEquals(10,map1.size()); - assertFalse(map1.isEmpty()); - assertEquals((Object) 9, map1.lastKey()); - assertEquals((Object) 9, map1.lastEntry().getValue()); - assertEquals((Object) 0, map1.firstKey()); - assertEquals((Object) 0, map1.firstEntry().getValue()); - } - - @Test public void WriteDBInt_lastKey_set() { - int numberOfRecords = 1000; - - /** Creates connections to MapDB */ - DB db1 = DBMaker.newMemoryDB().make(); - - - /** Creates maps */ - NavigableSet map1 = db1.getTreeSet("column1"); - - /** Inserts initial values in maps */ - for (int i = 0; i < numberOfRecords; i++) { - map1.add(i); - } - - - assertEquals((Object) (numberOfRecords - 1), map1.last()); - - map1.clear(); - - /** Inserts some values in maps */ - for (int i = 0; i < 10; i++) { - map1.add(i); - } - - assertEquals(10,map1.size()); - assertFalse(map1.isEmpty()); - assertEquals((Object) 9, map1.last()); - assertEquals((Object) 0, map1.first()); - } - - @Test public void WriteDBInt_lastKey_middle() { - int numberOfRecords = 1000; - - /** Creates connections to MapDB */ - DB db1 = DBMaker.newMemoryDB().make(); - - - /** Creates maps */ - ConcurrentNavigableMap map1 = db1.getTreeMap("column1"); - - /** Inserts initial values in maps */ - for (int i = 0; i < numberOfRecords; i++) { - map1.put(i, i); - } - - - assertEquals((Object) (numberOfRecords - 1), map1.lastKey()); - - map1.clear(); - - /** Inserts some values in maps */ - for (int i = 100; i < 110; i++) { - map1.put(i, i); - } - - assertEquals(10,map1.size()); - assertFalse(map1.isEmpty()); - assertEquals((Object) 109, map1.lastKey()); - assertEquals((Object) 109, map1.lastEntry().getValue()); - assertEquals((Object) 100, map1.firstKey()); - assertEquals((Object) 100, map1.firstEntry().getValue()); - } - - @Test public void WriteDBInt_lastKey_set_middle() { - int numberOfRecords = 1000; - - /** Creates connections to MapDB */ - DB db1 = DBMaker.newMemoryDB().make(); - - - /** Creates maps */ - NavigableSet map1 = db1.getTreeSet("column1"); - - /** Inserts initial values in maps */ - for (int i = 0; i < numberOfRecords; i++) { - map1.add(i); - } - - - assertEquals((Object) (numberOfRecords - 1), map1.last()); - - map1.clear(); - - /** Inserts some values in maps */ - for (int i = 100; i < 110; i++) { - map1.add(i); - } - - assertEquals(10,map1.size()); - assertFalse(map1.isEmpty()); - assertEquals((Object) 109, map1.last()); - assertEquals((Object) 100, map1.first()); - } - - @Test public void randomStructuralCheck(){ - Random r = new Random(); - BTreeMap map = DBMaker.newMemoryDB().transactionDisable().make().createTreeMap("aa") - .keySerializer(BTreeKeySerializer.ZERO_OR_POSITIVE_INT) - .valueSerializer(Serializer.INTEGER) - .make(); - - int max =100000; - - for(int i=0;i { - - protected boolean valsOutside = false; - - public static class Outside extends BTreeMapTest2{ - { - valsOutside = true; - } - } - - public BTreeMapTest2() { - super(false, false, true, true, true, true, false); - } - - Engine r; - - - @Override - protected void setUp() throws Exception { - r = new StoreDirect(null); - } - - @Override - protected void tearDown() throws Exception { - r.close(); - } - - @Override - protected Integer getKeyNotInPopulatedMap() throws UnsupportedOperationException { - return -100; - } - - @Override - protected String getValueNotInPopulatedMap() throws UnsupportedOperationException { - return "XYZ"; - } - - @Override - protected String getSecondValueNotInPopulatedMap() throws UnsupportedOperationException { - return "AAAA"; - } - - @Override - protected ConcurrentMap makeEmptyMap() throws UnsupportedOperationException { - - return new BTreeMap(r,BTreeMap.createRootRef(r,BTreeKeySerializer.BASIC, Serializer.BASIC, 0), - 6,valsOutside,0, BTreeKeySerializer.BASIC,Serializer.BASIC, - 0); - } - - @Override - protected ConcurrentMap makePopulatedMap() throws UnsupportedOperationException { - ConcurrentMap map = makeEmptyMap(); - for (int i = 0; i < 100; i++){ - map.put(i, "aa" + i); - } - return map; - } - -} diff --git a/src/test/java/org/mapdb/BTreeMapTest3.java b/src/test/java/org/mapdb/BTreeMapTest3.java deleted file mode 100644 index b62457f77..000000000 --- a/src/test/java/org/mapdb/BTreeMapTest3.java +++ /dev/null @@ -1,273 +0,0 @@ -package org.mapdb; - -import java.util.*; -import java.util.concurrent.ConcurrentNavigableMap; - -/** - * This code comes from GoogleCollections, was modified for JDBM by Jan Kotek - * - * Tests representing the contract of {@link java.util.SortedMap}. Concrete subclasses of - * this base class test conformance of concrete {@link java.util.SortedMap} subclasses to - * that contract. - * - * @author Jared Levy - * - */ -public class BTreeMapTest3 - extends ConcurrentMapInterfaceTest { - - public BTreeMapTest3() { - super(false, false, true, true, true, true, false); - } - - - @Override - protected Integer getKeyNotInPopulatedMap() throws UnsupportedOperationException { - return -100; - } - - @Override - protected String getValueNotInPopulatedMap() throws UnsupportedOperationException { - return "XYZ"; - } - - @Override - protected String getSecondValueNotInPopulatedMap() throws UnsupportedOperationException { - return "ASD"; - } - - @Override - protected ConcurrentNavigableMap makeEmptyMap() throws UnsupportedOperationException { - return DBMaker.newMemoryDB().make().getTreeMap("test"); - } - - public static class Outside extends BTreeMapTest3{ - @Override - protected ConcurrentNavigableMap makeEmptyMap() throws UnsupportedOperationException { - return DBMaker.newMemoryDB().make().createTreeMap("test").valuesOutsideNodesEnable().make(); - } - - } - - @Override - protected ConcurrentNavigableMap makePopulatedMap() throws UnsupportedOperationException { - ConcurrentNavigableMap map = makeEmptyMap(); - for (int i = 0; i < 100; i++){ - if(i%11==0||i%7==0) continue; - - map.put(i, "aa" + i); - } - return map; - } - @Override - protected ConcurrentNavigableMap makeEitherMap() { - try { - return makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return makeEmptyMap(); - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) // Needed for null comparator - public void testOrdering() { - final SortedMap map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - Iterator iterator = map.keySet().iterator(); - Integer prior = iterator.next(); - Comparator comparator = map.comparator(); - while (iterator.hasNext()) { - Integer current = iterator.next(); - if (comparator == null) { - Comparable comparable = (Comparable) prior; - assertTrue(comparable.compareTo(current) < 0); - } else { - assertTrue(map.comparator().compare(prior, current) < 0); - } - current = prior; - } - } - - - - public void testFirstKeyNonEmpty() { - final SortedMap map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - Integer expected = map.keySet().iterator().next(); - assertEquals(expected, map.firstKey()); - assertInvariants(map); - } - - - public void testLastKeyNonEmpty() { - final SortedMap map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - Integer expected = null; - for (Integer key : map.keySet()) { - expected = key; - } - assertEquals(expected, map.lastKey()); - assertInvariants(map); - } - - private static List toList(Collection collection) { - return new ArrayList(collection); - } - - private static List subListSnapshot( - List list, int fromIndex, int toIndex) { - List subList = new ArrayList(); - for (int i = fromIndex; i < toIndex; i++) { - subList.add(list.get(i)); - } - return Collections.unmodifiableList(subList); - } - - public void testHeadMap() { - final NavigableMap map; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - List> list = toList(map.entrySet()); - for (int i = 0; i < list.size(); i++) { - List> expected = subListSnapshot(list, 0, i); - SortedMap headMap = map.headMap(list.get(i).getKey()); - assertEquals(expected, toList(headMap.entrySet())); - } - - for (int i = 0; i < list.size(); i++) { - List> expected = subListSnapshot(list, 0, i+1); - SortedMap headMap = map.headMap(list.get(i).getKey(),true); - assertEquals(expected, toList(headMap.entrySet())); - } - - for (int i = 0; i < list.size(); i++) { - List> expected = subListSnapshot(list, 0, i); - SortedMap headMap = map.headMap(list.get(i).getKey(),false); - assertEquals(expected, toList(headMap.entrySet())); - } - - - } - - - - public void testTailMap() { - final NavigableMap map; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - List> list = toList(map.entrySet()); - for (int i = 0; i < list.size(); i++) { - List> expected = subListSnapshot(list, i, list.size()); - SortedMap tailMap = map.tailMap(list.get(i).getKey()); - assertEquals(expected, toList(tailMap.entrySet())); - } - - for (int i = 0; i < list.size(); i++) { - List> expected = subListSnapshot(list, i, list.size()); - SortedMap tailMap = map.tailMap(list.get(i).getKey(),true); - assertEquals(expected, toList(tailMap.entrySet())); - } - - for (int i = 0; i < list.size(); i++) { - List> expected = subListSnapshot(list, i+1, list.size()); - SortedMap tailMap = map.tailMap(list.get(i).getKey(),false); - assertEquals(expected, toList(tailMap.entrySet())); - } - - - } - - - public void testSubMap() { - final NavigableMap map; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - List> list = toList(map.entrySet()); - for (int i = 0; i < list.size(); i++) { - for (int j = i; j < list.size(); j++) { - List> expected = subListSnapshot(list, i, j); - SortedMap subMap - = map.subMap(list.get(i).getKey(), list.get(j).getKey()); - assertEquals(expected, toList(subMap.entrySet())); - assertEquals(expected.size(), subMap.size()); - assertEquals(expected.size(), subMap.keySet().size()); - assertEquals(expected.size(), subMap.entrySet().size()); - assertEquals(expected.size(), subMap.values().size()); - } - } - - for (int i = 0; i < list.size(); i++) { - for (int j = i; j < list.size(); j++) { - List> expected = subListSnapshot(list, i, j+1); - SortedMap subMap - = map.subMap(list.get(i).getKey(), true, list.get(j).getKey(), true); - assertEquals(expected, toList(subMap.entrySet())); - assertEquals(expected.size(), subMap.size()); - assertEquals(expected.size(), subMap.keySet().size()); - assertEquals(expected.size(), subMap.entrySet().size()); - assertEquals(expected.size(), subMap.values().size()); - } - } - - - for (int i = 0; i < list.size(); i++) { - for (int j = i; j < list.size(); j++) { - List> expected = subListSnapshot(list, i+1, j); - SortedMap subMap - = map.subMap(list.get(i).getKey(), false, list.get(j).getKey(), false); - assertEquals(expected, toList(subMap.entrySet())); - assertEquals(expected.size(), subMap.size()); - assertEquals(expected.size(), subMap.keySet().size()); - assertEquals(expected.size(), subMap.entrySet().size()); - assertEquals(expected.size(), subMap.values().size()); - } - } - - - - } - - public void testSubMapIllegal() { - final SortedMap map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - if (map.size() < 2) { - return; - } - Iterator iterator = map.keySet().iterator(); - Integer first = iterator.next(); - Integer second = iterator.next(); - try { - map.subMap(second, first); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - } - } - - - - -} diff --git a/src/test/java/org/mapdb/BTreeMapTest4.java b/src/test/java/org/mapdb/BTreeMapTest4.java deleted file mode 100644 index 9eb8b69d1..000000000 --- a/src/test/java/org/mapdb/BTreeMapTest4.java +++ /dev/null @@ -1,1909 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 - * - * http://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. - */ - -package org.mapdb; - -import java.io.Serializable; -import java.text.CollationKey; -import java.text.Collator; -import java.util.*; -import java.util.Map.Entry; - - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class BTreeMapTest4 extends junit.framework.TestCase { - - protected BTreeMap newBTreeMap(Map map) { - BTreeMap ret = DBMaker.newMemoryDB() - .cacheDisable() - .transactionDisable().make() - .createTreeMap("test").nodeSize(6).make(); - ret.putAll(map); - return ret; - } - - protected BTreeMap newBTreeMap(Comparator comp) { - return DBMaker.newMemoryDB() - .cacheDisable() - .transactionDisable().make() - .createTreeMap("test").nodeSize(6).comparator(comp).make(); - } - - protected BTreeMap newBTreeMap() { - return DBMaker.newMemoryDB() - .cacheDisable() - .transactionDisable().make() - .getTreeMap("test"); - } - - public static class Outside extends BTreeMapTest4{ - - @Override protected BTreeMap newBTreeMap(Map map) { - BTreeMap ret = DBMaker.newMemoryDB() - .cacheDisable() - .transactionDisable().make() - .createTreeMap("test").nodeSize(6) - .valuesOutsideNodesEnable() - .make(); - ret.putAll(map); - return ret; - } - - @Override protected BTreeMap newBTreeMap(Comparator comp) { - return DBMaker.newMemoryDB() - .cacheDisable() - .transactionDisable().make() - .createTreeMap("test").nodeSize(6).comparator(comp) - .valuesOutsideNodesEnable() - .make(); - } - - @Override protected BTreeMap newBTreeMap() { - return DBMaker.newMemoryDB() - .cacheDisable() - .transactionDisable().make() - .createTreeMap("test") - .valuesOutsideNodesEnable() - .make(); - } - } - - public static class ReversedComparator implements Comparator,Serializable { - private static final long serialVersionUID = -6582440135976043229L; - - public int compare(Object o1, Object o2) { - return -(((Comparable) o1).compareTo(o2)); - } - - public boolean equals(Object o1, Object o2) { - return (((Comparable) o1).compareTo(o2)) == 0; - } - } - - // Regression for Harmony-1026 - public static class MockComparator> implements - Comparator, Serializable { - - private static final long serialVersionUID = 5203668427652057645L; - - public int compare(T o1, T o2) { - if (o1 == o2) { - return 0; - } - if (null == o1 || null == o2) { - return -1; - } - T c1 = o1; - T c2 = o2; - return c1.compareTo(c2); - } - } - - - BTreeMap tm; - - Object objArray[] = new Object[1000]; - - @Override - protected void tearDown() throws Exception { - tm.engine.close(); - } - - /** - * @tests java.util.TreeMap#TreeMap(java.util.Comparator) - */ - public void test_ConstructorLjava_util_Comparator() { - // Test for method java.util.TreeMap(java.util.Comparator) - Comparator comp = new ReversedComparator(); - BTreeMap reversedTreeMap = newBTreeMap(comp); - assertEquals("TreeMap answered incorrect comparator", reversedTreeMap - .comparator().getClass().toString(),comp.getClass().toString()); - reversedTreeMap.put(new Integer(1).toString(), new Integer(1)); - reversedTreeMap.put(new Integer(2).toString(), new Integer(2)); - assertTrue("TreeMap does not use comparator (firstKey was incorrect)", - reversedTreeMap.firstKey().equals(new Integer(2).toString())); - assertTrue("TreeMap does not use comparator (lastKey was incorrect)", - reversedTreeMap.lastKey().equals(new Integer(1).toString())); - - } - - - - - - /** - * @tests java.util.TreeMap#clear() - */ - public void test_clear() { - // Test for method void java.util.TreeMap.clear() - tm.clear(); - assertEquals("Cleared map returned non-zero size", 0, tm.size()); - } - - - /** - * @tests java.util.TreeMap#comparator() - */ - public void test_comparator() { - // Test for method java.util.Comparator java.util.TreeMap.comparator()\ - Comparator comp = new ReversedComparator(); - BTreeMap reversedTreeMap = newBTreeMap(comp); - assertTrue("TreeMap answered incorrect comparator", reversedTreeMap - .comparator() == comp); - reversedTreeMap.put(new Integer(1).toString(), new Integer(1)); - reversedTreeMap.put(new Integer(2).toString(), new Integer(2)); - assertTrue("TreeMap does not use comparator (firstKey was incorrect)", - reversedTreeMap.firstKey().equals(new Integer(2).toString())); - assertTrue("TreeMap does not use comparator (lastKey was incorrect)", - reversedTreeMap.lastKey().equals(new Integer(1).toString())); - } - - /** - * @tests java.util.TreeMap#containsKey(java.lang.Object) - */ - public void test_containsKeyLjava_lang_Object() { - // Test for method boolean - // java.util.TreeMap.containsKey(java.lang.Object) - assertTrue("Returned false for valid key", tm.containsKey("95")); - assertTrue("Returned true for invalid key", !tm.containsKey("XXXXX")); - } - - /** - * @tests java.util.TreeMap#containsValue(java.lang.Object) - */ - public void test_containsValueLjava_lang_Object() { - // Test for method boolean - // java.util.TreeMap.containsValue(java.lang.Object) - assertTrue("Returned false for valid value", tm - .containsValue(objArray[986])); - assertTrue("Returned true for invalid value", !tm - .containsValue(new Object())); - } - - /** - * @tests java.util.TreeMap#entrySet() - */ - public void test_entrySet() { - // Test for method java.util.Set java.util.TreeMap.entrySet() - Set anEntrySet = tm.entrySet(); - Iterator entrySetIterator = anEntrySet.iterator(); - assertTrue("EntrySet is incorrect size", - anEntrySet.size() == objArray.length); - Map.Entry entry; - while (entrySetIterator.hasNext()) { - entry = (Map.Entry) entrySetIterator.next(); - assertEquals("EntrySet does not contain correct mappings", tm - .get(entry.getKey()), entry.getValue()); - } - } - - /** - * @tests java.util.TreeMap#firstKey() - */ - public void test_firstKey() { - // Test for method java.lang.Object java.util.TreeMap.firstKey() - assertEquals("Returned incorrect first key", "0", tm.firstKey()); - } - - /** - * @tests java.util.TreeMap#get(java.lang.Object) - */ - public void test_getLjava_lang_Object() { - // Test for method java.lang.Object - // java.util.TreeMap.get(java.lang.Object) - Object o = Long.MIN_VALUE; - tm.put("Hello", o); - assertEquals("Failed to get mapping", tm.get("Hello"), o); - - // Test for the same key & same value - tm = newBTreeMap(); - Object o2 = Long.MAX_VALUE; - Integer key1 = 1; - Integer key2 = 2; - assertNull(tm.put(key1, o)); - assertNull(tm.put(key2, o)); - assertEquals(2, tm.values().size()); - assertEquals(2, tm.keySet().size()); - assertEquals(tm.get(key1), tm.get(key2)); - assertEquals(o, tm.put(key1, o2)); - assertEquals(o2, tm.get(key1)); - } - - - // Regression for ill-behaved collator - static class IllBehavedCollator extends Collator implements Serializable { - private static final long serialVersionUID = 3009434843065697796L; - - @Override - public int compare(String o1, String o2) { - if (o1 == null) { - return 0; - } - return o1.compareTo(o2); - } - - @Override - public CollationKey getCollationKey(String string) { - return null; - } - - @Override - public int hashCode() { - return 0; - } - } - - /** - * @tests java.util.TreeMap#headMap(java.lang.Object) - */ - public void test_headMapLjava_lang_Object() { - // Test for method java.util.SortedMap - // java.util.TreeMap.headMap(java.lang.Object) - Map head = tm.headMap("100"); - assertEquals("Returned map of incorrect size", 3, head.size()); - assertTrue("Returned incorrect elements", head.containsKey("0") - && head.containsValue(new Integer("1")) - && head.containsKey("10")); - - // Regression for Harmony-1026 - BTreeMap map = newBTreeMap( - new MockComparator()); - map.put(1, 2.1); - map.put(2, 3.1); - map.put(3, 4.5); - map.put(7, 21.3); - - SortedMap smap = map.headMap(-1); - assertEquals(0, smap.size()); - - Set keySet = smap.keySet(); - assertEquals(0, keySet.size()); - - Set> entrySet = smap.entrySet(); - assertEquals(0, entrySet.size()); - - Collection valueCollection = smap.values(); - assertEquals(0, valueCollection.size()); - -// // Regression for Harmony-1066 -// assertTrue(head instanceof Serializable); - - - BTreeMap treemap = newBTreeMap(new IllBehavedCollator()); -// assertEquals(0, treemap.headMap(null).size()); - - treemap = newBTreeMap(); - SortedMap headMap = treemap.headMap("100"); - headMap.headMap("100"); - - SortedMap intMap,sub; - int size = 16; - intMap = newBTreeMap(); - for(int i=0; i tm = newBTreeMap(); - tm.put("001", "VAL001"); - tm.put("003", "VAL003"); - tm.put("002", "VAL002"); - SortedMap sm = tm; - String firstKey = sm.firstKey(); - String lastKey=""; - for (int i = 1; i <= tm.size(); i++) { - try{ - lastKey = sm.lastKey(); - } - catch(NoSuchElementException excep){ - fail("NoSuchElementException thrown when there are elements in the map"); - } - sm = sm.subMap(firstKey, lastKey); - } - } - - /** - * @tests java.util.TreeMap#put(java.lang.Object, java.lang.Object) - */ - public void test_putLjava_lang_ObjectLjava_lang_Object() { - // Test for method java.lang.Object - // java.util.TreeMap.put(java.lang.Object, java.lang.Object) - Object o = Long.MIN_VALUE; - tm.put("Hello", o); - assertEquals("Failed to put mapping", tm.get("Hello") , o); - - // regression for Harmony-780 - tm = newBTreeMap(); - assertNull(tm.put(new Object(), new Object())); - try { - tm.put(new Integer(1), new Object()); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - - tm = newBTreeMap(); - assertNull(tm.put(new Integer(1), new Object())); - - try { - tm.put(new Object(), new Object()); - fail("Should throw a ClassCastException"); - } catch (ClassCastException e) { - // expected - } - -// // regression for Harmony-2474 -// // but RI6 changes its behavior -// // so the test changes too -// tm = newBTreeMap(); -// try { -// tm.remove(o); -// fail("should throw ClassCastException"); -// } catch (ClassCastException e) { -// //expected -// } - } - - /** - * @tests java.util.TreeMap#putAll(java.util.Map) - */ - public void test_putAllLjava_util_Map() { - // Test for method void java.util.TreeMap.putAll(java.util.Map) - BTreeMap x = newBTreeMap(); - x.putAll(tm); - assertTrue("Map incorrect size after put", x.size() == tm.size()); - for (Object element : objArray) { - assertTrue("Failed to put all elements", x.get(element.toString()) - .equals(element)); - } - } - - /** - * @tests java.util.TreeMap#remove(java.lang.Object) - */ - public void test_removeLjava_lang_Object() { - // Test for method java.lang.Object - // java.util.TreeMap.remove(java.lang.Object) - tm.remove("990"); - assertTrue("Failed to remove mapping", !tm.containsKey("990")); - - } - - /** - * @tests java.util.TreeMap#size() - */ - public void test_size() { - // Test for method int java.util.TreeMap.size() - assertEquals("Returned incorrect size", 1000, tm.size()); - assertEquals("Returned incorrect size", 447, tm.headMap("500").size()); - assertEquals("Returned incorrect size", 1000, tm.headMap("null").size()); - assertEquals("Returned incorrect size", 0, tm.headMap("").size()); - assertEquals("Returned incorrect size", 448, tm.headMap("500a").size()); - assertEquals("Returned incorrect size", 553, tm.tailMap("500").size()); - assertEquals("Returned incorrect size", 0, tm.tailMap("null").size()); - assertEquals("Returned incorrect size", 1000, tm.tailMap("").size()); - assertEquals("Returned incorrect size", 552, tm.tailMap("500a").size()); - assertEquals("Returned incorrect size", 111, tm.subMap("500", "600") - .size()); - try { - tm.subMap("null", "600"); - fail("Should throw an IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - assertEquals("Returned incorrect size", 1000, tm.subMap("", "null") - .size()); - } - - /** - * @tests java.util.TreeMap#subMap(java.lang.Object, java.lang.Object) - */ - public void test_subMapLjava_lang_ObjectLjava_lang_Object() { - // Test for method java.util.SortedMap - // java.util.TreeMap.subMap(java.lang.Object, java.lang.Object) - SortedMap subMap = tm.subMap(objArray[100].toString(), objArray[109] - .toString()); - assertEquals("subMap is of incorrect size", 9, subMap.size()); - for (int counter = 100; counter < 109; counter++) { - assertTrue("SubMap contains incorrect elements", subMap.get( - objArray[counter].toString()).equals(objArray[counter])); - } - - try { - tm.subMap(objArray[9].toString(), objArray[1].toString()); - fail("end key less than start key should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // Regression test for typo in lastKey method - SortedMap map = newBTreeMap(); - map.put("1", "one"); //$NON-NLS-1$ //$NON-NLS-2$ - map.put("2", "two"); //$NON-NLS-1$ //$NON-NLS-2$ - map.put("3", "three"); //$NON-NLS-1$ //$NON-NLS-2$ - assertEquals("3", map.lastKey()); - SortedMap sub = map.subMap("1", "3"); //$NON-NLS-1$ //$NON-NLS-2$ - assertEquals("2", sub.lastKey()); //$NON-NLS-1$ - - BTreeMap t = newBTreeMap(); - try { - SortedMap th = t.subMap(null,new Object()); - fail("Should throw a NullPointerException"); - } catch( NullPointerException npe) { - // expected - } - } - - - /** - * @tests java.util.TreeMap#subMap(java.lang.Object, java.lang.Object) - */ - public void test_subMap_Iterator() { - BTreeMap map = newBTreeMap(); - - String[] keys = { "1", "2", "3" }; - String[] values = { "one", "two", "three" }; - for (int i = 0; i < keys.length; i++) { - map.put(keys[i], values[i]); - } - - assertEquals(3, map.size()); - - Map subMap = map.subMap("", "test"); - assertEquals(3, subMap.size()); - - Set entrySet = subMap.entrySet(); - Iterator iter = entrySet.iterator(); - int size = 0; - while (iter.hasNext()) { - Map.Entry entry = (Map.Entry) iter - .next(); - assertTrue(map.containsKey(entry.getKey())); - assertTrue(map.containsValue(entry.getValue())); - size++; - } - assertEquals(map.size(), size); - - Set keySet = subMap.keySet(); - iter = keySet.iterator(); - size = 0; - while (iter.hasNext()) { - String key = (String) iter.next(); - assertTrue(map.containsKey(key)); - size++; - } - assertEquals(map.size(), size); - } - - - /** - * @tests java.util.TreeMap#tailMap(java.lang.Object) - */ - public void test_tailMapLjava_lang_Object() { - // Test for method java.util.SortedMap - // java.util.TreeMap.tailMap(java.lang.Object) - Map tail = tm.tailMap(objArray[900].toString()); - assertTrue("Returned map of incorrect size : " + tail.size(), tail - .size() == (objArray.length - 900) + 9); - for (int i = 900; i < objArray.length; i++) { - assertTrue("Map contains incorrect entries", tail - .containsValue(objArray[i])); - } - -// // Regression for Harmony-1066 -// assertTrue(tail instanceof Serializable); - - SortedMap intMap,sub; - int size = 16; - intMap = newBTreeMap(); - for(int i=0; i hs = new HashSet(); - hs.add(new Integer(0)); - hs.add(new Integer(25)); - hs.add(new Integer(99)); - assertTrue( - "UnmodifiableCollectionTest - should contain set of 0, 25, and 99", - col.containsAll(hs)); - hs.add(new Integer(100)); - assertTrue( - "UnmodifiableCollectionTest - should not contain set of 0, 25, 99 and 100", - !col.containsAll(hs)); - - // isEmpty - assertTrue("UnmodifiableCollectionTest - should not be empty", !col - .isEmpty()); - - // iterator - Iterator it = col.iterator(); - SortedSet ss = new TreeSet(); - while (it.hasNext()) { - ss.add(it.next()); - } - it = ss.iterator(); - for (int counter = 0; it.hasNext(); counter++) { - int nextValue = it.next().intValue(); - assertTrue( - "UnmodifiableCollectionTest - Iterator returned wrong value. Wanted: " - + counter + " got: " + nextValue, - nextValue == counter); - } - - // size - assertTrue( - "UnmodifiableCollectionTest - returned wrong size. Wanted 100, got: " - + col.size(), col.size() == 100); - - // toArray - Object[] objArray; - objArray = col.toArray(); - for (int counter = 0; it.hasNext(); counter++) { - assertTrue( - "UnmodifiableCollectionTest - toArray returned incorrect array", - objArray[counter] == it.next()); - } - - // toArray (Object[]) - objArray = new Object[100]; - col.toArray(objArray); - for (int counter = 0; it.hasNext(); counter++) { - assertTrue( - "UnmodifiableCollectionTest - toArray(Object) filled array incorrectly", - objArray[counter] == it.next()); - } - col.remove(new Integer(0)); - assertTrue( - "Removing from the values collection should remove from the original map", - !myTreeMap.containsValue(new Integer(0))); - assertEquals(99, col.size()); - j = 0; - for (Iterator iter = col.iterator(); iter.hasNext();) { - Object element = iter.next(); - j++; - } - assertEquals(99, j); - - } - - /** - * @tests java.util.TreeMap the values() method in sub maps - */ - public void test_subMap_values_size() { - BTreeMap myTreeMap = newBTreeMap(); - for (int i = 0; i < 1000; i++) { - myTreeMap.put(i, objArray[i]); - } - // Test for method values() in subMaps - Collection vals = myTreeMap.subMap(200, 400).values(); - assertTrue("Returned collection of incorrect size", vals.size() == 200); - for (int i = 200; i < 400; i++) { - assertTrue("Collection contains incorrect elements" + i, vals - .contains(objArray[i])); - } - assertEquals(200,vals.toArray().length); - vals.remove(objArray[300]); - assertTrue( - "Removing from the values collection should remove from the original map", - !myTreeMap.containsValue(objArray[300])); - assertTrue("Returned collection of incorrect size", vals.size() == 199); - assertEquals(199,vals.toArray().length); - - myTreeMap.put(300, objArray[300]); - // Test for method values() in subMaps - vals = myTreeMap.headMap(400).values(); - assertEquals("Returned collection of incorrect size", vals.size(), 400); - for (int i = 0; i < 400; i++) { - assertTrue("Collection contains incorrect elements "+i, vals - .contains(objArray[i])); - } - assertEquals(400,vals.toArray().length); - vals.remove(objArray[300]); - assertTrue( - "Removing from the values collection should remove from the original map", - !myTreeMap.containsValue(objArray[300])); - assertTrue("Returned collection of incorrect size", vals.size() == 399); - assertEquals(399,vals.toArray().length); - - myTreeMap.put(300, objArray[300]); - // Test for method values() in subMaps - vals = myTreeMap.tailMap(400).values(); - assertEquals("Returned collection of incorrect size", vals.size(), 600); - for (int i = 400; i < 1000; i++) { - assertTrue("Collection contains incorrect elements "+i, vals - .contains(objArray[i])); - } - assertEquals(600,vals.toArray().length); - vals.remove(objArray[600]); - assertTrue( - "Removing from the values collection should remove from the original map", - !myTreeMap.containsValue(objArray[600])); - assertTrue("Returned collection of incorrect size", vals.size() == 599); - assertEquals(599,vals.toArray().length); - - - myTreeMap.put(600, objArray[600]); - // Test for method values() in subMaps - vals = myTreeMap.tailMap(401).values(); - assertEquals("Returned collection of incorrect size", vals.size(), 599); - for (int i = 401; i < 1000; i++) { - assertTrue("Collection contains incorrect elements "+i, vals - .contains(objArray[i])); - } - assertEquals(599,vals.toArray().length); - vals.remove(objArray[600]); - assertTrue( - "Removing from the values collection should remove from the original map", - !myTreeMap.containsValue(objArray[600])); - assertTrue("Returned collection of incorrect size", vals.size() == 598); - assertEquals(598,vals.toArray().length); - - myTreeMap.put(600, objArray[600]); - // Test for method values() in subMaps - vals = myTreeMap.headMap(401).values(); - assertEquals("Returned collection of incorrect size", vals.size(), 401); - for (int i = 0; i <= 400; i++) { - assertTrue("Collection contains incorrect elements "+i, vals - .contains(objArray[i])); - } - assertEquals(401,vals.toArray().length); - vals.remove(objArray[300]); - assertTrue( - "Removing from the values collection should remove from the original map", - !myTreeMap.containsValue(objArray[300])); - assertTrue("Returned collection of incorrect size", vals.size() == 400); - assertEquals(400,vals.toArray().length); - - } - - /** - * @tests java.util.TreeMap#subMap() - */ - public void test_subMap_Iterator2() { - BTreeMap map = newBTreeMap(); - - String[] keys = { "1", "2", "3" }; - String[] values = { "one", "two", "three" }; - for (int i = 0; i < keys.length; i++) { - map.put(keys[i], values[i]); - } - - assertEquals(3, map.size()); - - Map subMap = map.subMap("", "test"); - assertEquals(3, subMap.size()); - - Set entrySet = subMap.entrySet(); - Iterator iter = entrySet.iterator(); - int size = 0; - while (iter.hasNext()) { - Map.Entry entry = (Map.Entry) iter - .next(); - assertTrue(map.containsKey(entry.getKey())); - assertTrue(map.containsValue(entry.getValue())); - size++; - } - assertEquals(map.size(), size); - - Set keySet = subMap.keySet(); - iter = keySet.iterator(); - size = 0; - while (iter.hasNext()) { - String key = (String) iter.next(); - assertTrue(map.containsKey(key)); - size++; - } - assertEquals(map.size(), size); - } - - - /** - * @tests {@link java.util.TreeMap#firstEntry()} - */ - public void test_firstEntry() throws Exception { - Integer testint = new Integer(-1); - Integer testint10000 = new Integer(-10000); - Integer testint9999 = new Integer(-9999); - assertEquals(objArray[0].toString(), tm.firstEntry().getKey()); - assertEquals(objArray[0], tm.firstEntry().getValue()); - tm.put(testint.toString(), testint); - assertEquals(testint.toString(), tm.firstEntry().getKey()); - assertEquals(testint, tm.firstEntry().getValue()); - tm.put(testint10000.toString(), testint10000); - assertEquals(testint.toString(), tm.firstEntry().getKey()); - assertEquals(testint, tm.firstEntry().getValue()); - tm.put(testint9999.toString(), testint9999); - assertEquals(testint.toString(), tm.firstEntry().getKey()); - Entry entry = tm.firstEntry(); - assertEquals(testint, entry.getValue()); - assertEntry(entry); - tm.clear(); - assertNull(tm.firstEntry()); - } - - /** - * @tests {@link java.util.TreeMap#lastEntry() - */ - public void test_lastEntry() throws Exception { - Integer testint10000 = new Integer(10000); - Integer testint9999 = new Integer(9999); - assertEquals(objArray[999].toString(), tm.lastEntry().getKey()); - assertEquals(objArray[999], tm.lastEntry().getValue()); - tm.put(testint10000.toString(), testint10000); - assertEquals(objArray[999].toString(), tm.lastEntry().getKey()); - assertEquals(objArray[999], tm.lastEntry().getValue()); - tm.put(testint9999.toString(), testint9999); - assertEquals(testint9999.toString(), tm.lastEntry().getKey()); - Entry entry = tm.lastEntry(); - assertEquals(testint9999, entry.getValue()); - assertEntry(entry); - tm.clear(); - assertNull(tm.lastEntry()); - } - - /** - * @tests {@link java.util.TreeMap#pollFirstEntry() - */ - public void test_pollFirstEntry() throws Exception { - Integer testint = new Integer(-1); - Integer testint10000 = new Integer(-10000); - Integer testint9999 = new Integer(-9999); - assertEquals(objArray[0].toString(), tm.pollFirstEntry().getKey()); - assertEquals(objArray[1], tm.pollFirstEntry().getValue()); - assertEquals(objArray[10], tm.pollFirstEntry().getValue()); - tm.put(testint.toString(), testint); - tm.put(testint10000.toString(), testint10000); - assertEquals(testint.toString(), tm.pollFirstEntry().getKey()); - assertEquals(testint10000, tm.pollFirstEntry().getValue()); - tm.put(testint9999.toString(), testint9999); - assertEquals(testint9999.toString(), tm.pollFirstEntry().getKey()); - Entry entry = tm.pollFirstEntry(); - assertEntry(entry); - assertEquals(objArray[100], entry.getValue()); - tm.clear(); - assertNull(tm.pollFirstEntry()); - } - - /** - * @tests {@link java.util.TreeMap#pollLastEntry() - */ - public void test_pollLastEntry() throws Exception { - Integer testint10000 = new Integer(10000); - Integer testint9999 = new Integer(9999); - assertEquals(objArray[999].toString(), tm.pollLastEntry().getKey()); - assertEquals(objArray[998], tm.pollLastEntry().getValue()); - assertEquals(objArray[997], tm.pollLastEntry().getValue()); - tm.put(testint10000.toString(), testint10000); - assertEquals(objArray[996], tm.pollLastEntry().getValue()); - tm.put(testint9999.toString(), testint9999); - assertEquals(testint9999.toString(), tm.pollLastEntry().getKey()); - Entry entry = tm.pollLastEntry(); - assertEquals(objArray[995], entry.getValue()); - assertEntry(entry); - tm.clear(); - assertNull(tm.pollLastEntry()); - } - - public void testLastFirstEntryOnEmpty(){ - tm.clear(); - assertNull(tm.firstEntry()); - assertNull(tm.lastEntry()); - } - - /** - * @tests {@link java.util.TreeMap#lowerEntry(Object) - */ - public void test_lowerEntry() throws Exception { - Integer testint10000 = new Integer(10000); - Integer testint9999 = new Integer(9999); - assertEquals(objArray[999], tm.lowerEntry(testint9999.toString()) - .getValue()); - assertEquals(objArray[100], tm.lowerEntry(testint10000.toString()) - .getValue()); - tm.put(testint10000.toString(), testint10000); - tm.put(testint9999.toString(), testint9999); - assertEquals(objArray[999], tm.lowerEntry(testint9999.toString()) - .getValue()); - Entry entry = tm.lowerEntry(testint10000.toString()); - assertEquals(objArray[100], entry.getValue()); - assertEntry(entry); - try { - tm.lowerEntry(testint10000); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - try { - tm.lowerEntry(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - tm.clear(); - assertNull(tm.lowerEntry(testint9999.toString())); -// assertNull(tm.lowerEntry(null)); - } - - /** - * @tests {@link java.util.TreeMap#lowerKey(Object) - */ - public void test_lowerKey() throws Exception { - Integer testint10000 = new Integer(10000); - Integer testint9999 = new Integer(9999); - assertEquals(objArray[999].toString(), tm.lowerKey(testint9999 - .toString())); - assertEquals(objArray[100].toString(), tm.lowerKey(testint10000 - .toString())); - tm.put(testint10000.toString(), testint10000); - tm.put(testint9999.toString(), testint9999); - assertEquals(objArray[999].toString(), tm.lowerKey(testint9999 - .toString())); - assertEquals(objArray[100].toString(), tm.lowerKey(testint10000 - .toString())); - try { - tm.lowerKey(testint10000); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - try { - tm.lowerKey(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - tm.clear(); - assertNull(tm.lowerKey(testint9999.toString())); -// assertNull(tm.lowerKey(null)); - } - - /** - * @tests {@link java.util.TreeMap#floorEntry(Object) - */ - public void test_floorEntry() throws Exception { - Integer testint10000 = new Integer(10000); - Integer testint9999 = new Integer(9999); - assertEquals(objArray[999], tm.floorEntry(testint9999.toString()) - .getValue()); - assertEquals(objArray[100], tm.floorEntry(testint10000.toString()) - .getValue()); - tm.put(testint10000.toString(), testint10000); - tm.put(testint9999.toString(), testint9999); - assertEquals(testint9999, tm.floorEntry(testint9999.toString()) - .getValue()); - Entry entry = tm.floorEntry(testint10000.toString()); - assertEquals(testint10000, entry.getValue()); - assertEntry(entry); - try { - tm.floorEntry(testint10000); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - try { - tm.floorEntry(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - tm.clear(); - assertNull(tm.floorEntry(testint9999.toString())); - } - - /** - * @tests {@link java.util.TreeMap#floorKey(Object) - */ - public void test_floorKey() throws Exception { - Integer testint10000 = new Integer(10000); - Integer testint9999 = new Integer(9999); - assertEquals(objArray[999].toString(), tm.floorKey(testint9999 - .toString())); - assertEquals(objArray[100].toString(), tm.floorKey(testint10000 - .toString())); - tm.put(testint10000.toString(), testint10000); - tm.put(testint9999.toString(), testint9999); - assertEquals(testint9999.toString(), tm - .floorKey(testint9999.toString())); - assertEquals(testint10000.toString(), tm.floorKey(testint10000 - .toString())); - try { - tm.floorKey(testint10000); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - try { - tm.floorKey(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - tm.clear(); - assertNull(tm.floorKey(testint9999.toString())); -// assertNull(tm.floorKey(null)); - } - - /** - * @tests {@link java.util.TreeMap#ceilingEntry(Object) - */ - public void test_ceilingEntry() throws Exception { - Integer testint100 = new Integer(100); - Integer testint = new Integer(-1); - assertEquals(objArray[0], tm.ceilingEntry(testint.toString()) - .getValue()); - assertEquals(objArray[100], tm.ceilingEntry(testint100.toString()) - .getValue()); - tm.put(testint.toString(), testint); - tm.put(testint100.toString(), testint); - assertEquals(testint, tm.ceilingEntry(testint.toString()).getValue()); - Entry entry = tm.ceilingEntry(testint100.toString()); - assertEquals(testint, entry.getValue()); - assertEntry(entry); - try { - tm.ceilingEntry(testint100); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - try { - tm.ceilingEntry(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } -// tm.clear(); -// assertNull(tm.ceilingEntry(testint.toString())); -// assertNull(tm.ceilingEntry(null)); - } - - /** - * @tests {@link java.util.TreeMap#ceilingKey(Object) - */ - public void test_ceilingKey() throws Exception { - Integer testint100 = new Integer(100); - Integer testint = new Integer(-1); - assertEquals(objArray[0].toString(), tm.ceilingKey(testint.toString())); - assertEquals(objArray[100].toString(), tm.ceilingKey(testint100 - .toString())); - tm.put(testint.toString(), testint); - tm.put(testint100.toString(), testint); - assertEquals(testint.toString(), tm.ceilingKey(testint.toString())); - assertEquals(testint100.toString(), tm - .ceilingKey(testint100.toString())); - try { - tm.ceilingKey(testint100); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - try { - tm.ceilingKey(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } -// tm.clear(); -// assertNull(tm.ceilingKey(testint.toString())); -// assertNull(tm.ceilingKey(null)); - } - - /** - * @tests {@link java.util.TreeMap#higherEntry(Object) - */ - public void test_higherEntry() throws Exception { - Integer testint9999 = new Integer(9999); - Integer testint10000 = new Integer(10000); - Integer testint100 = new Integer(100); - Integer testint = new Integer(-1); - assertEquals(objArray[0], tm.higherEntry(testint.toString()).getValue()); - assertEquals(objArray[101], tm.higherEntry(testint100.toString()) - .getValue()); - assertEquals(objArray[101], tm.higherEntry(testint10000.toString()) - .getValue()); - tm.put(testint9999.toString(), testint); - tm.put(testint100.toString(), testint); - tm.put(testint10000.toString(), testint); - assertEquals(objArray[0], tm.higherEntry(testint.toString()).getValue()); - assertEquals(testint, tm.higherEntry(testint100.toString()).getValue()); - Entry entry = tm.higherEntry(testint10000.toString()); - assertEquals(objArray[101], entry.getValue()); - assertEntry(entry); - assertNull(tm.higherEntry(testint9999.toString())); - try { - tm.higherEntry(testint100); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - try { - tm.higherEntry(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } -// tm.clear(); -// assertNull(tm.higherEntry(testint.toString())); -// assertNull(tm.higherEntry(null)); - } - - /** - * @tests {@link java.util.TreeMap#higherKey(Object) - */ - public void test_higherKey() throws Exception { - Integer testint9999 = new Integer(9999); - Integer testint10000 = new Integer(10000); - Integer testint100 = new Integer(100); - Integer testint = new Integer(-1); - assertEquals(objArray[0].toString(), tm.higherKey(testint.toString())); - assertEquals(objArray[101].toString(), tm.higherKey(testint100 - .toString())); - assertEquals(objArray[101].toString(), tm.higherKey(testint10000 - .toString())); - tm.put(testint9999.toString(), testint); - tm.put(testint100.toString(), testint); - tm.put(testint10000.toString(), testint); - assertEquals(objArray[0].toString(), tm.higherKey(testint.toString())); - assertEquals(testint10000.toString(), tm.higherKey(testint100 - .toString())); - assertEquals(objArray[101].toString(), tm.higherKey(testint10000 - .toString())); - assertNull(tm.higherKey(testint9999.toString())); - try { - tm.higherKey(testint100); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - try { - tm.higherKey(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } -// tm.clear(); -// assertNull(tm.higherKey(testint.toString())); -// assertNull(tm.higherKey(null)); - } - - public void test_navigableKeySet() throws Exception { - Integer testint9999 = new Integer(9999); - Integer testint10000 = new Integer(10000); - Integer testint100 = new Integer(100); - Integer testint0 = new Integer(0); - NavigableSet set = tm.navigableKeySet(); - assertFalse(set.contains(testint9999.toString())); - tm.put(testint9999.toString(), testint9999); - assertTrue(set.contains(testint9999.toString())); - tm.remove(testint9999.toString()); - assertFalse(set.contains(testint9999.toString())); - try { - set.add(new Object()); - fail("should throw UnsupportedOperationException"); - } catch (UnsupportedOperationException e) { - // expected - } - try { - set.add(null); - fail("should throw UnsupportedOperationException"); - } catch (UnsupportedOperationException e) { - // expected - } - try { - set.addAll(null); - fail("should throw UnsupportedOperationException"); - } catch (NullPointerException e) { - // expected - } - Collection collection = new LinkedList(); - set.addAll(collection); - try { - collection.add(new Object()); - set.addAll(collection); - fail("should throw UnsupportedOperationException"); - } catch (UnsupportedOperationException e) { - // expected - } - set.remove(testint100.toString()); - assertFalse(tm.containsKey(testint100.toString())); - assertTrue(tm.containsKey(testint0.toString())); - Iterator iter = set.iterator(); - iter.next(); - iter.remove(); - assertFalse(tm.containsKey(testint0.toString())); - collection.add(new Integer(200).toString()); - set.retainAll(collection); - assertEquals(1, tm.size()); - set.removeAll(collection); - assertEquals(0, tm.size()); - tm.put(testint10000.toString(), testint10000); - assertEquals(1, tm.size()); - set.clear(); - assertEquals(0, tm.size()); - } - - private void assertEntry(Entry entry) { - try { - entry.setValue(new Object()); - fail("should throw UnsupportedOperationException"); - } catch (UnsupportedOperationException e) { - // expected - } - assertEquals((entry.getKey() == null ? 0 : entry.getKey().hashCode()) - ^ (entry.getValue() == null ? 0 : entry.getValue().hashCode()), - entry.hashCode()); - assertEquals(entry.toString(), entry.getKey() + "=" + entry.getValue()); - } - - /** - * @tests java.util.TreeMap#subMap(java.lang.Object,boolean, - * java.lang.Object,boolean) - */ - public void test_subMapLjava_lang_ObjectZLjava_lang_ObjectZ() { - // normal case - SortedMap subMap = tm.subMap(objArray[100].toString(), true, - objArray[109].toString(), true); - assertEquals("subMap is of incorrect size", 10, subMap.size()); - subMap = tm.subMap(objArray[100].toString(), true, objArray[109] - .toString(), false); - assertEquals("subMap is of incorrect size", 9, subMap.size()); - for (int counter = 100; counter < 109; counter++) { - assertTrue("SubMap contains incorrect elements", subMap.get( - objArray[counter].toString()).equals(objArray[counter])); - } - subMap = tm.subMap(objArray[100].toString(), false, objArray[109] - .toString(), true); - assertEquals("subMap is of incorrect size", 9, subMap.size()); - assertNull(subMap.get(objArray[100].toString())); - - // Exceptions - try { - tm.subMap(objArray[9].toString(), true, objArray[1].toString(), - true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - try { - tm.subMap(objArray[9].toString(), false, objArray[1].toString(), - false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - try { - tm.subMap(null, true, null, true); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - try { - tm.subMap(null, false, objArray[100], true); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - try { - tm.subMap(new LinkedList(), false, objArray[100], true); - fail("should throw ClassCastException"); - } catch (ClassCastException e) { - // expected - } - - // use integer elements to test - BTreeMap treeMapInt = newBTreeMap(); - assertEquals(0, treeMapInt.subMap(new Integer(-1), true, - new Integer(100), true).size()); - for (int i = 0; i < 100; i++) { - treeMapInt.put(new Integer(i), new Integer(i).toString()); - } - SortedMap result = treeMapInt.subMap(new Integer(-1), - true, new Integer(100), true); - assertEquals(100, result.size()); - result.put(new Integer(-1), new Integer(-1).toString()); - assertEquals(101, result.size()); - assertEquals(101, treeMapInt.size()); - result = treeMapInt - .subMap(new Integer(50), true, new Integer(60), true); - assertEquals(11, result.size()); - try { - result.put(new Integer(-2), new Integer(-2).toString()); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - assertEquals(11, result.size()); - treeMapInt.remove(new Integer(50)); - assertEquals(100, treeMapInt.size()); - assertEquals(10, result.size()); - result.remove(new Integer(60)); - assertEquals(99, treeMapInt.size()); - assertEquals(9, result.size()); - SortedMap result2 = null; - try { - result2 = result.subMap(new Integer(-2), new Integer(100)); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - result2 = result.subMap(new Integer(50), new Integer(60)); - assertEquals(9, result2.size()); - - // sub map of sub map - NavigableMap mapIntObj = newBTreeMap(); - for (int i = 0; i < 10; ++i) { - mapIntObj.put(i, new Object()); - } - mapIntObj = mapIntObj.subMap(5, false, 9, true); - assertEquals(4, mapIntObj.size()); - mapIntObj = mapIntObj.subMap(5, false, 9, true); - assertEquals(4, mapIntObj.size()); - mapIntObj = mapIntObj.subMap(5, false, 6, false); - assertEquals(0, mapIntObj.size()); - - // a special comparator dealing with null key - tm = newBTreeMap(new SpecialNullableComparator()); - tm.put(new String("1st"), 1); - tm.put(new String("2nd"), 2); - tm.put(new String("3rd"), 3); - String nullKey = "0"; - tm.put(nullKey, -1); - SortedMap s = tm.subMap(nullKey, "3rd"); - assertEquals(3, s.size()); - assertTrue(s.containsValue(-1)); - assertTrue(s.containsValue(1)); - assertTrue(s.containsValue(2)); - assertTrue(s.containsKey(nullKey)); - assertFalse(s.containsKey("3nd")); - // RI fails here - // assertTrue(s.containsKey("1st")); - // assertTrue(s.containsKey("2nd")); - s = tm.descendingMap(); - s = s.tailMap("3rd"); - // assertEquals(4, s.size()); - assertTrue(s.containsValue(-1)); - assertTrue(s.containsValue(1)); - assertTrue(s.containsValue(2)); - assertTrue(s.containsValue(3)); -// assertFalse(s.containsKey(null)); - assertTrue(s.containsKey("1st")); - assertTrue(s.containsKey("2nd")); - assertTrue(s.containsKey("3rd")); - } - - // a special comparator dealing with null key - static public class SpecialNullableComparator implements Comparator,Serializable { - private static final long serialVersionUID = -5651263776100656076L; - - public int compare(Object o1, Object o2) { - if (o1 == null) { - return -1; - } - return ((String) o1).compareTo((String) o2); - } - } - - - - - /** - * @tests java.util.TreeMap#headMap(java.lang.Object,boolea) - */ - public void test_headMapLjava_lang_ObjectZL() { - // normal case - SortedMap subMap = tm.headMap(objArray[100].toString(), true); - assertEquals("subMap is of incorrect size", 4, subMap.size()); - subMap = tm.headMap(objArray[109].toString(), true); - assertEquals("subMap is of incorrect size", 13, subMap.size()); - for (int counter = 100; counter < 109; counter++) { - assertTrue("SubMap contains incorrect elements", subMap.get( - objArray[counter].toString()).equals(objArray[counter])); - } - subMap = tm.headMap(objArray[100].toString(), false); - assertEquals("subMap is of incorrect size", 3, subMap.size()); - assertNull(subMap.get(objArray[100].toString())); - - // Exceptions - assertEquals(0, tm.headMap("", true).size()); - assertEquals(0, tm.headMap("", false).size()); - - try { - tm.headMap(null, true); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - try { - tm.headMap(null, false); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } -// try { -// tm.headMap(new Object(), true); -// fail("should throw ClassCastException"); -// } catch (ClassCastException e) { -// // expected -// } -// try { -// tm.headMap(new Object(), false); -// fail("should throw ClassCastException"); -// } catch (ClassCastException e) { -// // expected -// } - - // use integer elements to test - BTreeMap treeMapInt = newBTreeMap(); - assertEquals(0, treeMapInt.headMap(new Integer(-1), true).size()); - for (int i = 0; i < 100; i++) { - treeMapInt.put(new Integer(i), new Integer(i).toString()); - } - SortedMap result = treeMapInt - .headMap(new Integer(101)); - assertEquals(100, result.size()); - try { - result.put(new Integer(101), new Integer(101).toString()); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - assertEquals(100, result.size()); - assertEquals(100, treeMapInt.size()); - result = treeMapInt.headMap(new Integer(50), true); - assertEquals(51, result.size()); - result.put(new Integer(-1), new Integer(-1).toString()); - assertEquals(52, result.size()); - - treeMapInt.remove(new Integer(40)); - assertEquals(100, treeMapInt.size()); - assertEquals(51, result.size()); - result.remove(new Integer(30)); - assertEquals(99, treeMapInt.size()); - assertEquals(50, result.size()); - SortedMap result2 = null; - try { - result.subMap(new Integer(-2), new Integer(100)); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - try { - result.subMap(new Integer(1), new Integer(100)); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - result2 = result.subMap(new Integer(-2), new Integer(48)); - assertEquals(47,result2.size()); - - result2 = result.subMap(new Integer(40), new Integer(50)); - assertEquals(9, result2.size()); - - - // head map of head map - NavigableMap mapIntObj = newBTreeMap(); - for (int i = 0; i < 10; ++i) { - mapIntObj.put(i, new Object()); - } - mapIntObj = mapIntObj.headMap(5, false); - assertEquals(5, mapIntObj.size()); - mapIntObj = mapIntObj.headMap(5, false); - assertEquals(5, mapIntObj.size()); - mapIntObj = mapIntObj.tailMap(5, false); - assertEquals(0, mapIntObj.size()); - } - - /** - * @tests java.util.TreeMap#tailMap(java.lang.Object,boolea) - */ - public void test_tailMapLjava_lang_ObjectZL() { - // normal case - SortedMap subMap = tm.tailMap(objArray[100].toString(), true); - assertEquals("subMap is of incorrect size", 997, subMap.size()); - subMap = tm.tailMap(objArray[109].toString(), true); - assertEquals("subMap is of incorrect size", 988, subMap.size()); - for (int counter = 119; counter > 110; counter--) { - assertTrue("SubMap contains incorrect elements", subMap.get( - objArray[counter].toString()).equals(objArray[counter])); - } - subMap = tm.tailMap(objArray[100].toString(), false); - assertEquals("subMap is of incorrect size", 996, subMap.size()); - assertNull(subMap.get(objArray[100].toString())); - - // Exceptions - assertEquals(1000, tm.tailMap("", true).size()); - assertEquals(1000, tm.tailMap("", false).size()); - - try { - tm.tailMap(null, true); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - try { - tm.tailMap(null, false); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } -// try { -// tm.tailMap(new Object(), true); -// fail("should throw ClassCastException"); -// } catch (ClassCastException e) { -// // expected -// } -// try { -// tm.tailMap(new Object(), false); -// fail("should throw ClassCastException"); -// } catch (ClassCastException e) { -// // expected -// } - - // use integer elements to test - BTreeMap treeMapInt = newBTreeMap(); - assertEquals(0, treeMapInt.tailMap(new Integer(-1), true).size()); - for (int i = 0; i < 100; i++) { - treeMapInt.put(new Integer(i), new Integer(i).toString()); - } - SortedMap result = treeMapInt.tailMap(new Integer(1)); - assertEquals(99, result.size()); - try { - result.put(new Integer(-1), new Integer(-1).toString()); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - assertEquals(99, result.size()); - assertEquals(100, treeMapInt.size()); - result = treeMapInt.tailMap(new Integer(50), true); - assertEquals(50, result.size()); - result.put(new Integer(101), new Integer(101).toString()); - assertEquals(51, result.size()); - - treeMapInt.remove(new Integer(60)); - assertEquals(100, treeMapInt.size()); - assertEquals(50, result.size()); - result.remove(new Integer(70)); - assertEquals(99, treeMapInt.size()); - assertEquals(49, result.size()); - SortedMap result2 = null; - try { - result2 = result.subMap(new Integer(-2), new Integer(100)); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // expected - } - result2 = result.subMap(new Integer(60), new Integer(70)); - assertEquals(9, result2.size()); - - - // tail map of tail map - NavigableMap mapIntObj = newBTreeMap(); - for (int i = 0; i < 10; ++i) { - mapIntObj.put(i, new Object()); - } - mapIntObj = mapIntObj.tailMap(5, false); - assertEquals(4, mapIntObj.size()); - mapIntObj = mapIntObj.tailMap(5, false); - assertEquals(4, mapIntObj.size()); - mapIntObj = mapIntObj.headMap(5, false); - assertEquals(0, mapIntObj.size()); - } - - - public void test_descendingMap_subMap() throws Exception { - BTreeMap tm = newBTreeMap(); - for (int i = 0; i < 10; ++i) { - tm.put(i, new Object()); - } - NavigableMap descMap = tm.descendingMap(); - assertEquals(7, descMap.subMap(8, true, 1, false).size()); - assertEquals(4, descMap.headMap(6, true).size()); - assertEquals(2, descMap.tailMap(2, false).size()); - - // sub map of sub map of descendingMap - NavigableMap mapIntObj = newBTreeMap(); - for (int i = 0; i < 10; ++i) { - mapIntObj.put(i, new Object()); - } - mapIntObj = mapIntObj.descendingMap(); - NavigableMap subMapIntObj = mapIntObj.subMap(9, true, - 5, false); - assertEquals(4, subMapIntObj.size()); - subMapIntObj = subMapIntObj.subMap(9, true, 5, false); - assertEquals(4, subMapIntObj.size()); - subMapIntObj = subMapIntObj.subMap(6, false, 5, false); - assertEquals(0, subMapIntObj.size()); - - subMapIntObj = mapIntObj.headMap(5, false); - assertEquals(4, subMapIntObj.size()); - subMapIntObj = subMapIntObj.headMap(5, false); - assertEquals(4, subMapIntObj.size()); - subMapIntObj = subMapIntObj.tailMap(5, false); - assertEquals(0, subMapIntObj.size()); - - subMapIntObj = mapIntObj.tailMap(5, false); - assertEquals(5, subMapIntObj.size()); - subMapIntObj = subMapIntObj.tailMap(5, false); - assertEquals(5, subMapIntObj.size()); - subMapIntObj = subMapIntObj.headMap(5, false); - assertEquals(0, subMapIntObj.size()); - } - - - private void illegalFirstNullKeyMapTester(NavigableMap map) { - try { - map.get(null); - fail("Should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - try { - map.put("NormalKey", "value"); - fail("Should throw NullPointerException"); - } catch (NullPointerException e) { - // expected - } - Set keySet = map.keySet(); - assertTrue(!keySet.isEmpty()); - assertEquals(1, keySet.size()); - for (String key : keySet) { - assertEquals(key, null); - try { - map.get(key); - fail("Should throw NullPointerException"); - } catch (NullPointerException e) { - // ignore - } - } - Set> entrySet = map.entrySet(); - assertTrue(!entrySet.isEmpty()); - assertEquals(1, entrySet.size()); - for (Entry entry : entrySet) { - assertEquals(null, entry.getKey()); - assertEquals("NullValue", entry.getValue()); - } - Collection values = map.values(); - assertTrue(!values.isEmpty()); - assertEquals(1, values.size()); - for (String value : values) { - assertEquals("NullValue", value); - } - - try { - map.headMap(null, true); - fail("Should throw NullPointerException"); - } catch (NullPointerException e) { - // ignore - } - try { - map.headMap(null, false); - fail("Should throw NullPointerException"); - } catch (NullPointerException e) { - // ignore - } - - try { - map.subMap(null, false, null, false); - fail("Should throw NullPointerException"); - } catch (NullPointerException e) { - // ignore - } - try { - map.subMap(null, true, null, true); - fail("Should throw NullPointerException"); - } catch (NullPointerException e) { - // ignore - } - try { - map.tailMap(null, true); - fail("Should throw NullPointerException"); - } catch (NullPointerException e) { - // ignore - } - try { - map.tailMap(null, false); - fail("Should throw NullPointerException"); - } catch (NullPointerException e) { - // ignore - } - } - - /** - * Tests equals() method. - * Tests that no ClassCastException will be thrown in all cases. - * Regression test for HARMONY-1639. - */ - public void test_equals() throws Exception { - // comparing TreeMaps with different object types - Map m1 = newBTreeMap(); - Map m2 = newBTreeMap(); - m1.put("key1", "val1"); - m1.put("key2", "val2"); - m2.put(new Integer(1), "val1"); - m2.put(new Integer(2), "val2"); - assertFalse("Maps should not be equal 1", m1.equals(m2)); - assertFalse("Maps should not be equal 2", m2.equals(m1)); - - // comparing TreeMap with HashMap - m1 = newBTreeMap(); - m2 = new HashMap(); - m1.put("key", "val"); - m2.put(new Object(), "val"); - assertFalse("Maps should not be equal 3", m1.equals(m2)); - assertFalse("Maps should not be equal 4", m2.equals(m1)); - - // comparing TreeMaps with not-comparable objects inside - m1 = newBTreeMap(); - m2 = newBTreeMap(); - m1.put(new Object(), "val1"); - m2.put(new Object(), "val1"); - assertFalse("Maps should not be equal 5", m1.equals(m2)); - assertFalse("Maps should not be equal 6", m2.equals(m1)); - } - - public void test_remove_from_iterator() throws Exception { - Set set = tm.keySet(); - Iterator iter = set.iterator(); - iter.next(); - iter.remove(); - try{ - iter.remove(); - fail("should throw IllegalStateException"); - }catch (IllegalStateException e){ - // expected - } - } - - - public void test_iterator_next_(){ - Map m = tm.subMap("0", "1"); - Iterator it = m.entrySet().iterator(); - assertEquals("0=0",it.next().toString()); - while(it.hasNext()){} - try { - it.next(); - fail("should throw java.util.NoSuchElementException"); - }catch (Exception e){ - assertTrue(e instanceof java.util.NoSuchElementException); - } - } - - public void test_empty_subMap() throws Exception { - BTreeMap> tm = newBTreeMap(); - SortedMap> sm = tm.tailMap(1.1f); - assertTrue(sm.values().size() == 0); - } - - - - public void test_values_1(){ - BTreeMap treeMap = newBTreeMap(); - treeMap.put("firstKey", "firstValue"); - treeMap.put("secondKey", "secondValue"); - treeMap.put("thirdKey", "thirdValue"); - Object firstKey = treeMap.firstKey(); - SortedMap subMap = ((SortedMap)treeMap).subMap(firstKey, firstKey); - Iterator iter = subMap.values().iterator(); - } - - /** - * Sets up the fixture, for example, open a network connection. This method - * is called before a test is executed. - */ - @Override - protected void setUp() { - tm = newBTreeMap(); - for (int i = 0; i < objArray.length; i++) { - Object x = objArray[i] = new Integer(i); - tm.put(x.toString(), x); - } - } -} - diff --git a/src/test/java/org/mapdb/BTreeMapTest5.java b/src/test/java/org/mapdb/BTreeMapTest5.java deleted file mode 100644 index 8c8d66cae..000000000 --- a/src/test/java/org/mapdb/BTreeMapTest5.java +++ /dev/null @@ -1,1422 +0,0 @@ -package org.mapdb;/* -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -import java.util.*; -import java.util.concurrent.ConcurrentNavigableMap; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class BTreeMapTest5 extends JSR166TestCase { - - public static class Outside extends BTreeMapTest5{ - @Override - protected BTreeMap newMap() { - return DBMaker.newMemoryDB().make().createTreeMap("test").valuesOutsideNodesEnable().make(); - } - } - - protected BTreeMap newMap() { - return DBMaker.newMemoryDB().make().createTreeMap("test").make(); - } - - - /** - * Returns a new map from Integers 1-5 to Strings "A"-"E". - */ - private ConcurrentNavigableMap map5() { - ConcurrentNavigableMap map = newMap(); - assertTrue(map.isEmpty()); - map.put(zero, "Z"); - map.put(one, "A"); - map.put(five, "E"); - map.put(three, "C"); - map.put(two, "B"); - map.put(four, "D"); - map.put(seven, "F"); - assertFalse(map.isEmpty()); - assertEquals(7, map.size()); - return map.subMap(one, true, seven, false); - } - - - /** - * Returns a new map from Integers -5 to -1 to Strings "A"-"E". - */ - private ConcurrentNavigableMap dmap5() { - ConcurrentNavigableMap map = newMap(); - assertTrue(map.isEmpty()); - map.put(m1, "A"); - map.put(m5, "E"); - map.put(m3, "C"); - map.put(m2, "B"); - map.put(m4, "D"); - assertFalse(map.isEmpty()); - assertEquals(5, map.size()); - return map.descendingMap(); - } - - private ConcurrentNavigableMap map0() { - ConcurrentNavigableMap map = newMap(); - assertTrue(map.isEmpty()); - return map.tailMap(one, true); - } - - private ConcurrentNavigableMap dmap0() { - ConcurrentNavigableMap map = newMap(); - assertTrue(map.isEmpty()); - return map; - } - - /** - * clear removes all pairs - */ - public void testClear() { - ConcurrentNavigableMap map = map5(); - map.clear(); - assertEquals(0, map.size()); - } - - /** - * Maps with same contents are equal - */ - public void testEquals() { - ConcurrentNavigableMap map1 = map5(); - ConcurrentNavigableMap map2 = map5(); - assertEquals(map1, map2); - assertEquals(map2, map1); - map1.clear(); - assertFalse(map1.equals(map2)); - assertFalse(map2.equals(map1)); - } - - /** - * containsKey returns true for contained key - */ - public void testContainsKey() { - ConcurrentNavigableMap map = map5(); - assertTrue(map.containsKey(one)); - assertFalse(map.containsKey(zero)); - } - - /** - * containsValue returns true for held values - */ - public void testContainsValue() { - ConcurrentNavigableMap map = map5(); - assertTrue(map.containsValue("A")); - assertFalse(map.containsValue("Z")); - } - - /** - * get returns the correct element at the given key, - * or null if not present - */ - public void testGet() { - ConcurrentNavigableMap map = map5(); - assertEquals("A", (String)map.get(one)); - ConcurrentNavigableMap empty = map0(); - assertNull(empty.get(one)); - } - - /** - * isEmpty is true of empty map and false for non-empty - */ - public void testIsEmpty() { - ConcurrentNavigableMap empty = map0(); - ConcurrentNavigableMap map = map5(); - assertTrue(empty.isEmpty()); - assertFalse(map.isEmpty()); - } - - /** - * firstKey returns first key - */ - public void testFirstKey() { - ConcurrentNavigableMap map = map5(); - assertEquals(one, map.firstKey()); - } - - /** - * lastKey returns last key - */ - public void testLastKey() { - ConcurrentNavigableMap map = map5(); - assertEquals(five, map.lastKey()); - } - - /** - * keySet returns a Set containing all the keys - */ - public void testKeySet() { - ConcurrentNavigableMap map = map5(); - Set s = map.keySet(); - assertEquals(5, s.size()); - assertTrue(s.contains(one)); - assertTrue(s.contains(two)); - assertTrue(s.contains(three)); - assertTrue(s.contains(four)); - assertTrue(s.contains(five)); - } - - /** - * keySet is ordered - */ - public void testKeySetOrder() { - ConcurrentNavigableMap map = map5(); - Set s = map.keySet(); - Iterator i = s.iterator(); - Integer last = (Integer)i.next(); - assertEquals(last, one); - while (i.hasNext()) { - Integer k = (Integer)i.next(); - assertTrue(last.compareTo(k) < 0); - last = k; - } - } - - /** - * values collection contains all values - */ - public void testValues() { - ConcurrentNavigableMap map = map5(); - Collection s = map.values(); - assertEquals(5, s.size()); - assertTrue(s.contains("A")); - assertTrue(s.contains("B")); - assertTrue(s.contains("C")); - assertTrue(s.contains("D")); - assertTrue(s.contains("E")); - } - - /** - * keySet.toArray returns contains all keys - */ - public void testKeySetToArray() { - ConcurrentNavigableMap map = map5(); - Set s = map.keySet(); - Object[] ar = s.toArray(); - assertTrue(s.containsAll(Arrays.asList(ar))); - assertEquals(5, ar.length); - ar[0] = m10; - assertFalse(s.containsAll(Arrays.asList(ar))); - } - - /** - * descendingkeySet.toArray returns contains all keys - */ - public void testDescendingKeySetToArray() { - ConcurrentNavigableMap map = map5(); - Set s = map.descendingKeySet(); - Object[] ar = s.toArray(); - assertEquals(5, ar.length); - assertTrue(s.containsAll(Arrays.asList(ar))); - ar[0] = m10; - assertFalse(s.containsAll(Arrays.asList(ar))); - } - - /** - * Values.toArray contains all values - */ - - public void testValuesToArray() { - ConcurrentNavigableMap map = map5(); - Collection v = map.values(); - Object[] ar = v.toArray(); - ArrayList s = new ArrayList(Arrays.asList(ar)); - assertEquals(5, ar.length); - assertTrue(s.contains("A")); - assertTrue(s.contains("B")); - assertTrue(s.contains("C")); - assertTrue(s.contains("D")); - assertTrue(s.contains("E")); - } - - /** - * entrySet contains all pairs - */ - public void testEntrySet() { - ConcurrentNavigableMap map = map5(); - Set s = map.entrySet(); - assertEquals(5, s.size()); - Iterator it = s.iterator(); - while (it.hasNext()) { - Map.Entry e = (Map.Entry) it.next(); - assertTrue( - (e.getKey().equals(one) && e.getValue().equals("A")) || - (e.getKey().equals(two) && e.getValue().equals("B")) || - (e.getKey().equals(three) && e.getValue().equals("C")) || - (e.getKey().equals(four) && e.getValue().equals("D")) || - (e.getKey().equals(five) && e.getValue().equals("E"))); - } - } - - /** - * putAll adds all key-value pairs from the given map - */ - public void testPutAll() { - ConcurrentNavigableMap empty = map0(); - ConcurrentNavigableMap map = map5(); - empty.putAll(map); - assertEquals(5, empty.size()); - assertTrue(empty.containsKey(one)); - assertTrue(empty.containsKey(two)); - assertTrue(empty.containsKey(three)); - assertTrue(empty.containsKey(four)); - assertTrue(empty.containsKey(five)); - } - - /** - * putIfAbsent works when the given key is not present - */ - public void testPutIfAbsent() { - ConcurrentNavigableMap map = map5(); - map.putIfAbsent(six, "Z"); - assertTrue(map.containsKey(six)); - } - - /** - * putIfAbsent does not add the pair if the key is already present - */ - public void testPutIfAbsent2() { - ConcurrentNavigableMap map = map5(); - assertEquals("A", map.putIfAbsent(one, "Z")); - } - - /** - * replace fails when the given key is not present - */ - public void testReplace() { - ConcurrentNavigableMap map = map5(); - assertNull(map.replace(six, "Z")); - assertFalse(map.containsKey(six)); - } - - /** - * replace succeeds if the key is already present - */ - public void testReplace2() { - ConcurrentNavigableMap map = map5(); - assertNotNull(map.replace(one, "Z")); - assertEquals("Z", map.get(one)); - } - - /** - * replace value fails when the given key not mapped to expected value - */ - public void testReplaceValue() { - ConcurrentNavigableMap map = map5(); - assertEquals("A", map.get(one)); - assertFalse(map.replace(one, "Z", "Z")); - assertEquals("A", map.get(one)); - } - - /** - * replace value succeeds when the given key mapped to expected value - */ - public void testReplaceValue2() { - ConcurrentNavigableMap map = map5(); - assertEquals("A", map.get(one)); - assertTrue(map.replace(one, "A", "Z")); - assertEquals("Z", map.get(one)); - } - - /** - * remove removes the correct key-value pair from the map - */ - public void testRemove() { - ConcurrentNavigableMap map = map5(); - map.remove(five); - assertEquals(4, map.size()); - assertFalse(map.containsKey(five)); - } - - /** - * remove(key,value) removes only if pair present - */ - public void testRemove2() { - ConcurrentNavigableMap map = map5(); - assertTrue(map.containsKey(five)); - assertEquals("E", map.get(five)); - map.remove(five, "E"); - assertEquals(4, map.size()); - assertFalse(map.containsKey(five)); - map.remove(four, "A"); - assertEquals(4, map.size()); - assertTrue(map.containsKey(four)); - } - - /** - * lowerEntry returns preceding entry. - */ - public void testLowerEntry() { - ConcurrentNavigableMap map = map5(); - Map.Entry e1 = map.lowerEntry(three); - assertEquals(two, e1.getKey()); - - Map.Entry e2 = map.lowerEntry(six); - assertEquals(five, e2.getKey()); - - Map.Entry e3 = map.lowerEntry(one); - assertNull(e3); - - Map.Entry e4 = map.lowerEntry(zero); - assertNull(e4); - } - - /** - * higherEntry returns next entry. - */ - public void testHigherEntry() { - ConcurrentNavigableMap map = map5(); - Map.Entry e1 = map.higherEntry(three); - assertEquals(four, e1.getKey()); - - Map.Entry e2 = map.higherEntry(zero); - assertEquals(one, e2.getKey()); - - Map.Entry e3 = map.higherEntry(five); - assertNull(e3); - - Map.Entry e4 = map.higherEntry(six); - assertNull(e4); - } - - /** - * floorEntry returns preceding entry. - */ - public void testFloorEntry() { - ConcurrentNavigableMap map = map5(); - Map.Entry e1 = map.floorEntry(three); - assertEquals(three, e1.getKey()); - - Map.Entry e2 = map.floorEntry(six); - assertEquals(five, e2.getKey()); - - Map.Entry e3 = map.floorEntry(one); - assertEquals(one, e3.getKey()); - - Map.Entry e4 = map.floorEntry(zero); - assertNull(e4); - } - - /** - * ceilingEntry returns next entry. - */ - public void testCeilingEntry() { - ConcurrentNavigableMap map = map5(); - Map.Entry e1 = map.ceilingEntry(three); - assertEquals(three, e1.getKey()); - - Map.Entry e2 = map.ceilingEntry(zero); - assertEquals(one, e2.getKey()); - - Map.Entry e3 = map.ceilingEntry(five); - assertEquals(five, e3.getKey()); - - Map.Entry e4 = map.ceilingEntry(six); - assertNull(e4); - } - - /** - * pollFirstEntry returns entries in order - */ - public void testPollFirstEntry() { - ConcurrentNavigableMap map = map5(); - Map.Entry e = map.pollFirstEntry(); - assertEquals(one, e.getKey()); - assertEquals("A", e.getValue()); - e = map.pollFirstEntry(); - assertEquals(two, e.getKey()); - map.put(one, "A"); - e = map.pollFirstEntry(); - assertEquals(one, e.getKey()); - assertEquals("A", e.getValue()); - e = map.pollFirstEntry(); - assertEquals(three, e.getKey()); - map.remove(four); - e = map.pollFirstEntry(); - assertEquals(five, e.getKey()); - try { - e.setValue("A"); - shouldThrow(); - } catch (UnsupportedOperationException success) {} - e = map.pollFirstEntry(); - assertNull(e); - } - - /** - * pollLastEntry returns entries in order - */ - public void testPollLastEntry() { - ConcurrentNavigableMap map = map5(); - Map.Entry e = map.pollLastEntry(); - assertEquals(five, e.getKey()); - assertEquals("E", e.getValue()); - e = map.pollLastEntry(); - assertEquals(four, e.getKey()); - map.put(five, "E"); - e = map.pollLastEntry(); - assertEquals(five, e.getKey()); - assertEquals("E", e.getValue()); - e = map.pollLastEntry(); - assertEquals(three, e.getKey()); - map.remove(two); - e = map.pollLastEntry(); - assertEquals(one, e.getKey()); - try { - e.setValue("E"); - shouldThrow(); - } catch (UnsupportedOperationException success) {} - e = map.pollLastEntry(); - assertNull(e); - } - - /** - * size returns the correct values - */ - public void testSize() { - ConcurrentNavigableMap map = map5(); - ConcurrentNavigableMap empty = map0(); - assertEquals(0, empty.size()); - assertEquals(5, map.size()); - } - - /** - * toString contains toString of elements - */ - public void testToString() { - ConcurrentNavigableMap map = map5(); - String s = map.toString(); - for (int i = 1; i <= 5; ++i) { - assertTrue(s.contains(String.valueOf(i))); - } - } - - // Exception tests - - /** - * get(null) of nonempty map throws NPE - */ - public void testGet_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.get(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * containsKey(null) of nonempty map throws NPE - */ - public void testContainsKey_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.containsKey(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * containsValue(null) throws NPE - */ - public void testContainsValue_NullPointerException() { - try { - ConcurrentNavigableMap c = map0(); - c.containsValue(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * put(null,x) throws NPE - */ - public void testPut1_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.put(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * putIfAbsent(null, x) throws NPE - */ - public void testPutIfAbsent1_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.putIfAbsent(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * replace(null, x) throws NPE - */ - public void testReplace_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.replace(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * replace(null, x, y) throws NPE - */ - public void testReplaceValue_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.replace(null, one, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * remove(null) throws NPE - */ - public void testRemove1_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.remove(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * remove(null, x) throws NPE - */ - public void testRemove2_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.remove(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - -// /** -// * A deserialized map equals original -// */ -// public void testSerialization() throws Exception { -// NavigableMap x = map5(); -// NavigableMap y = serialClone(x); -// -// assertNotSame(x, y); -// assertEquals(x.size(), y.size()); -// assertEquals(x.toString(), y.toString()); -// assertEquals(x, y); -// assertEquals(y, x); -// } - - /** - * subMap returns map with keys in requested range - */ - public void testSubMapContents() { - ConcurrentNavigableMap map = map5(); - SortedMap sm = map.subMap(two, four); - assertEquals(two, sm.firstKey()); - assertEquals(three, sm.lastKey()); - assertEquals(2, sm.size()); - assertFalse(sm.containsKey(one)); - assertTrue(sm.containsKey(two)); - assertTrue(sm.containsKey(three)); - assertFalse(sm.containsKey(four)); - assertFalse(sm.containsKey(five)); - Iterator i = sm.keySet().iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - assertFalse(i.hasNext()); - Iterator j = sm.keySet().iterator(); - j.next(); - j.remove(); - assertFalse(map.containsKey(two)); - assertEquals(4, map.size()); - assertEquals(1, sm.size()); - assertEquals(three, sm.firstKey()); - assertEquals(three, sm.lastKey()); - assertEquals("C", sm.remove(three)); - assertTrue(sm.isEmpty()); - assertEquals(3, map.size()); - } - - public void testSubMapContents2() { - ConcurrentNavigableMap map = map5(); - SortedMap sm = map.subMap(two, three); - assertEquals(1, sm.size()); - assertEquals(two, sm.firstKey()); - assertEquals(two, sm.lastKey()); - assertFalse(sm.containsKey(one)); - assertTrue(sm.containsKey(two)); - assertFalse(sm.containsKey(three)); - assertFalse(sm.containsKey(four)); - assertFalse(sm.containsKey(five)); - Iterator i = sm.keySet().iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - assertFalse(i.hasNext()); - Iterator j = sm.keySet().iterator(); - j.next(); - j.remove(); - assertFalse(map.containsKey(two)); - assertEquals(4, map.size()); - assertEquals(0, sm.size()); - assertTrue(sm.isEmpty()); - assertSame(sm.remove(three), null); - assertEquals(4, map.size()); - } - - /** - * headMap returns map with keys in requested range - */ - public void testHeadMapContents() { - ConcurrentNavigableMap map = map5(); - SortedMap sm = map.headMap(four); - assertTrue(sm.containsKey(one)); - assertTrue(sm.containsKey(two)); - assertTrue(sm.containsKey(three)); - assertFalse(sm.containsKey(four)); - assertFalse(sm.containsKey(five)); - Iterator i = sm.keySet().iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(one, k); - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - assertFalse(i.hasNext()); - sm.clear(); - assertTrue(sm.isEmpty()); - assertEquals(2, map.size()); - assertEquals(four, map.firstKey()); - } - - /** - * headMap returns map with keys in requested range - */ - public void testTailMapContents() { - ConcurrentNavigableMap map = map5(); - SortedMap sm = map.tailMap(two); - assertFalse(sm.containsKey(one)); - assertTrue(sm.containsKey(two)); - assertTrue(sm.containsKey(three)); - assertTrue(sm.containsKey(four)); - assertTrue(sm.containsKey(five)); - Iterator i = sm.keySet().iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - k = (Integer)(i.next()); - assertEquals(four, k); - k = (Integer)(i.next()); - assertEquals(five, k); - assertFalse(i.hasNext()); - - Iterator ei = sm.entrySet().iterator(); - Map.Entry e; - e = (Map.Entry)(ei.next()); - assertEquals(two, e.getKey()); - assertEquals("B", e.getValue()); - e = (Map.Entry)(ei.next()); - assertEquals(three, e.getKey()); - assertEquals("C", e.getValue()); - e = (Map.Entry)(ei.next()); - assertEquals(four, e.getKey()); - assertEquals("D", e.getValue()); - e = (Map.Entry)(ei.next()); - assertEquals(five, e.getKey()); - assertEquals("E", e.getValue()); - assertFalse(i.hasNext()); - - SortedMap ssm = sm.tailMap(four); - assertEquals(four, ssm.firstKey()); - assertEquals(five, ssm.lastKey()); - assertEquals("D", ssm.remove(four)); - assertEquals(1, ssm.size()); - assertEquals(3, sm.size()); - assertEquals(4, map.size()); - } - - /** - * clear removes all pairs - */ - public void testDescendingClear() { - ConcurrentNavigableMap map = dmap5(); - map.clear(); - assertEquals(0, map.size()); - } - - /** - * Maps with same contents are equal - */ - public void testDescendingEquals() { - ConcurrentNavigableMap map1 = dmap5(); - ConcurrentNavigableMap map2 = dmap5(); - assertEquals(map1, map2); - assertEquals(map2, map1); - map1.clear(); - assertFalse(map1.equals(map2)); - assertFalse(map2.equals(map1)); - } - - /** - * containsKey returns true for contained key - */ - public void testDescendingContainsKey() { - ConcurrentNavigableMap map = dmap5(); - assertTrue(map.containsKey(m1)); - assertFalse(map.containsKey(zero)); - } - - /** - * containsValue returns true for held values - */ - public void testDescendingContainsValue() { - ConcurrentNavigableMap map = dmap5(); - assertTrue(map.containsValue("A")); - assertFalse(map.containsValue("Z")); - } - - /** - * get returns the correct element at the given key, - * or null if not present - */ - public void testDescendingGet() { - ConcurrentNavigableMap map = dmap5(); - assertEquals("A", (String)map.get(m1)); - ConcurrentNavigableMap empty = dmap0(); - assertNull(empty.get(m1)); - } - - /** - * isEmpty is true of empty map and false for non-empty - */ - public void testDescendingIsEmpty() { - ConcurrentNavigableMap empty = dmap0(); - ConcurrentNavigableMap map = dmap5(); - assertTrue(empty.isEmpty()); - assertFalse(map.isEmpty()); - } - - /** - * firstKey returns first key - */ - public void testDescendingFirstKey() { - ConcurrentNavigableMap map = dmap5(); - assertEquals(m1, map.firstKey()); - } - - /** - * lastKey returns last key - */ - public void testDescendingLastKey() { - ConcurrentNavigableMap map = dmap5(); - assertEquals(m5, map.lastKey()); - } - - /** - * keySet returns a Set containing all the keys - */ - public void testDescendingKeySet() { - ConcurrentNavigableMap map = dmap5(); - Set s = map.keySet(); - assertEquals(5, s.size()); - assertTrue(s.contains(m1)); - assertTrue(s.contains(m2)); - assertTrue(s.contains(m3)); - assertTrue(s.contains(m4)); - assertTrue(s.contains(m5)); - } - - /** - * keySet is ordered - */ - public void testDescendingKeySetOrder() { - ConcurrentNavigableMap map = dmap5(); - Set s = map.keySet(); - Iterator i = s.iterator(); - Integer last = (Integer)i.next(); - assertEquals(last, m1); - while (i.hasNext()) { - Integer k = (Integer)i.next(); - assertTrue(last.compareTo(k) > 0); - last = k; - } - } - - /** - * values collection contains all values - */ - public void testDescendingValues() { - ConcurrentNavigableMap map = dmap5(); - Collection s = map.values(); - assertEquals(5, s.size()); - assertTrue(s.contains("A")); - assertTrue(s.contains("B")); - assertTrue(s.contains("C")); - assertTrue(s.contains("D")); - assertTrue(s.contains("E")); - } - - /** - * keySet.toArray returns contains all keys - */ - public void testDescendingAscendingKeySetToArray() { - ConcurrentNavigableMap map = dmap5(); - Set s = map.keySet(); - Object[] ar = s.toArray(); - assertTrue(s.containsAll(Arrays.asList(ar))); - assertEquals(5, ar.length); - ar[0] = m10; - assertFalse(s.containsAll(Arrays.asList(ar))); - } - - /** - * descendingkeySet.toArray returns contains all keys - */ - public void testDescendingDescendingKeySetToArray() { - ConcurrentNavigableMap map = dmap5(); - Set s = map.descendingKeySet(); - Object[] ar = s.toArray(); - assertEquals(5, ar.length); - assertTrue(s.containsAll(Arrays.asList(ar))); - ar[0] = m10; - assertFalse(s.containsAll(Arrays.asList(ar))); - } - - /** - * Values.toArray contains all values - */ - public void testDescendingValuesToArray() { - ConcurrentNavigableMap map = dmap5(); - Collection v = map.values(); - Object[] ar = v.toArray(); - ArrayList s = new ArrayList(Arrays.asList(ar)); - assertEquals(5, ar.length); - assertTrue(s.contains("A")); - assertTrue(s.contains("B")); - assertTrue(s.contains("C")); - assertTrue(s.contains("D")); - assertTrue(s.contains("E")); - } - - /** - * entrySet contains all pairs - */ - public void testDescendingEntrySet() { - ConcurrentNavigableMap map = dmap5(); - Set s = map.entrySet(); - assertEquals(5, s.size()); - Iterator it = s.iterator(); - while (it.hasNext()) { - Map.Entry e = (Map.Entry) it.next(); - assertTrue( - (e.getKey().equals(m1) && e.getValue().equals("A")) || - (e.getKey().equals(m2) && e.getValue().equals("B")) || - (e.getKey().equals(m3) && e.getValue().equals("C")) || - (e.getKey().equals(m4) && e.getValue().equals("D")) || - (e.getKey().equals(m5) && e.getValue().equals("E"))); - } - } - - /** - * putAll adds all key-value pairs from the given map - */ - public void testDescendingPutAll() { - ConcurrentNavigableMap empty = dmap0(); - ConcurrentNavigableMap map = dmap5(); - empty.putAll(map); - assertEquals(5, empty.size()); - assertTrue(empty.containsKey(m1)); - assertTrue(empty.containsKey(m2)); - assertTrue(empty.containsKey(m3)); - assertTrue(empty.containsKey(m4)); - assertTrue(empty.containsKey(m5)); - } - - /** - * putIfAbsent works when the given key is not present - */ - public void testDescendingPutIfAbsent() { - ConcurrentNavigableMap map = dmap5(); - map.putIfAbsent(six, "Z"); - assertTrue(map.containsKey(six)); - } - - /** - * putIfAbsent does not add the pair if the key is already present - */ - public void testDescendingPutIfAbsent2() { - ConcurrentNavigableMap map = dmap5(); - assertEquals("A", map.putIfAbsent(m1, "Z")); - } - - /** - * replace fails when the given key is not present - */ - public void testDescendingReplace() { - ConcurrentNavigableMap map = dmap5(); - assertNull(map.replace(six, "Z")); - assertFalse(map.containsKey(six)); - } - - /** - * replace succeeds if the key is already present - */ - public void testDescendingReplace2() { - ConcurrentNavigableMap map = dmap5(); - assertNotNull(map.replace(m1, "Z")); - assertEquals("Z", map.get(m1)); - } - - /** - * replace value fails when the given key not mapped to expected value - */ - public void testDescendingReplaceValue() { - ConcurrentNavigableMap map = dmap5(); - assertEquals("A", map.get(m1)); - assertFalse(map.replace(m1, "Z", "Z")); - assertEquals("A", map.get(m1)); - } - - /** - * replace value succeeds when the given key mapped to expected value - */ - public void testDescendingReplaceValue2() { - ConcurrentNavigableMap map = dmap5(); - assertEquals("A", map.get(m1)); - assertTrue(map.replace(m1, "A", "Z")); - assertEquals("Z", map.get(m1)); - } - - /** - * remove removes the correct key-value pair from the map - */ - public void testDescendingRemove() { - ConcurrentNavigableMap map = dmap5(); - map.remove(m5); - assertEquals(4, map.size()); - assertFalse(map.containsKey(m5)); - } - - /** - * remove(key,value) removes only if pair present - */ - public void testDescendingRemove2() { - ConcurrentNavigableMap map = dmap5(); - assertTrue(map.containsKey(m5)); - assertEquals("E", map.get(m5)); - map.remove(m5, "E"); - assertEquals(4, map.size()); - assertFalse(map.containsKey(m5)); - map.remove(m4, "A"); - assertEquals(4, map.size()); - assertTrue(map.containsKey(m4)); - } - - /** - * lowerEntry returns preceding entry. - */ - public void testDescendingLowerEntry() { - ConcurrentNavigableMap map = dmap5(); - Map.Entry e1 = map.lowerEntry(m3); - assertEquals(m2, e1.getKey()); - - Map.Entry e2 = map.lowerEntry(m6); - assertEquals(m5, e2.getKey()); - - Map.Entry e3 = map.lowerEntry(m1); - assertNull(e3); - - Map.Entry e4 = map.lowerEntry(zero); - assertNull(e4); - } - - /** - * higherEntry returns next entry. - */ - public void testDescendingHigherEntry() { - ConcurrentNavigableMap map = dmap5(); - Map.Entry e1 = map.higherEntry(m3); - assertEquals(m4, e1.getKey()); - - Map.Entry e2 = map.higherEntry(zero); - assertEquals(m1, e2.getKey()); - - Map.Entry e3 = map.higherEntry(m5); - assertNull(e3); - - Map.Entry e4 = map.higherEntry(m6); - assertNull(e4); - } - - /** - * floorEntry returns preceding entry. - */ - public void testDescendingFloorEntry() { - ConcurrentNavigableMap map = dmap5(); - Map.Entry e1 = map.floorEntry(m3); - assertEquals(m3, e1.getKey()); - - Map.Entry e2 = map.floorEntry(m6); - assertEquals(m5, e2.getKey()); - - Map.Entry e3 = map.floorEntry(m1); - assertEquals(m1, e3.getKey()); - - Map.Entry e4 = map.floorEntry(zero); - assertNull(e4); - } - - /** - * ceilingEntry returns next entry. - */ - public void testDescendingCeilingEntry() { - ConcurrentNavigableMap map = dmap5(); - Map.Entry e1 = map.ceilingEntry(m3); - assertEquals(m3, e1.getKey()); - - Map.Entry e2 = map.ceilingEntry(zero); - assertEquals(m1, e2.getKey()); - - Map.Entry e3 = map.ceilingEntry(m5); - assertEquals(m5, e3.getKey()); - - Map.Entry e4 = map.ceilingEntry(m6); - assertNull(e4); - } - - /** - * pollFirstEntry returns entries in order - */ - public void testDescendingPollFirstEntry() { - ConcurrentNavigableMap map = dmap5(); - Map.Entry e = map.pollFirstEntry(); - assertEquals(m1, e.getKey()); - assertEquals("A", e.getValue()); - e = map.pollFirstEntry(); - assertEquals(m2, e.getKey()); - map.put(m1, "A"); - e = map.pollFirstEntry(); - assertEquals(m1, e.getKey()); - assertEquals("A", e.getValue()); - e = map.pollFirstEntry(); - assertEquals(m3, e.getKey()); - map.remove(m4); - e = map.pollFirstEntry(); - assertEquals(m5, e.getKey()); - try { - e.setValue("A"); - shouldThrow(); - } catch (UnsupportedOperationException success) {} - e = map.pollFirstEntry(); - assertNull(e); - } - - /** - * pollLastEntry returns entries in order - */ - public void testDescendingPollLastEntry() { - ConcurrentNavigableMap map = dmap5(); - Map.Entry e = map.pollLastEntry(); - assertEquals(m5, e.getKey()); - assertEquals("E", e.getValue()); - e = map.pollLastEntry(); - assertEquals(m4, e.getKey()); - map.put(m5, "E"); - e = map.pollLastEntry(); - assertEquals(m5, e.getKey()); - assertEquals("E", e.getValue()); - e = map.pollLastEntry(); - assertEquals(m3, e.getKey()); - map.remove(m2); - e = map.pollLastEntry(); - assertEquals(m1, e.getKey()); - try { - e.setValue("E"); - shouldThrow(); - } catch (UnsupportedOperationException success) {} - e = map.pollLastEntry(); - assertNull(e); - } - - /** - * size returns the correct values - */ - public void testDescendingSize() { - ConcurrentNavigableMap map = dmap5(); - ConcurrentNavigableMap empty = dmap0(); - assertEquals(0, empty.size()); - assertEquals(5, map.size()); - } - - /** - * toString contains toString of elements - */ - public void testDescendingToString() { - ConcurrentNavigableMap map = dmap5(); - String s = map.toString(); - for (int i = 1; i <= 5; ++i) { - assertTrue(s.contains(String.valueOf(i))); - } - } - - // Exception testDescendings - - /** - * get(null) of empty map throws NPE - */ - public void testDescendingGet_NullPointerException() { - try { - ConcurrentNavigableMap c = dmap5(); - c.get(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * containsKey(null) of empty map throws NPE - */ - public void testDescendingContainsKey_NullPointerException() { - try { - ConcurrentNavigableMap c = dmap5(); - c.containsKey(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * containsValue(null) throws NPE - */ - public void testDescendingContainsValue_NullPointerException() { - try { - ConcurrentNavigableMap c = dmap0(); - c.containsValue(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * put(null,x) throws NPE - */ - public void testDescendingPut1_NullPointerException() { - try { - ConcurrentNavigableMap c = dmap5(); - c.put(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * putIfAbsent(null, x) throws NPE - */ - public void testDescendingPutIfAbsent1_NullPointerException() { - try { - ConcurrentNavigableMap c = dmap5(); - c.putIfAbsent(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * replace(null, x) throws NPE - */ - public void testDescendingReplace_NullPointerException() { - try { - ConcurrentNavigableMap c = dmap5(); - c.replace(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * replace(null, x, y) throws NPE - */ - public void testDescendingReplaceValue_NullPointerException() { - try { - ConcurrentNavigableMap c = dmap5(); - c.replace(null, m1, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * remove(null) throws NPE - */ - public void testDescendingRemove1_NullPointerException() { - try { - ConcurrentNavigableMap c = dmap5(); - c.remove(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * remove(null, x) throws NPE - */ - public void testDescendingRemove2_NullPointerException() { - try { - ConcurrentNavigableMap c = dmap5(); - c.remove(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - -// /** -// * A deserialized map equals original -// */ -// public void testDescendingSerialization() throws Exception { -// NavigableMap x = dmap5(); -// NavigableMap y = serialClone(x); -// -// assertNotSame(x, y); -// assertEquals(x.size(), y.size()); -// assertEquals(x.toString(), y.toString()); -// assertEquals(x, y); -// assertEquals(y, x); -// } - - /** - * subMap returns map with keys in requested range - */ - public void testDescendingSubMapContents() { - ConcurrentNavigableMap map = dmap5(); - SortedMap sm = map.subMap(m2, m4); - assertEquals(m2, sm.firstKey()); - assertEquals(m3, sm.lastKey()); - assertEquals(2, sm.size()); - assertFalse(sm.containsKey(m1)); - assertTrue(sm.containsKey(m2)); - assertTrue(sm.containsKey(m3)); - assertFalse(sm.containsKey(m4)); - assertFalse(sm.containsKey(m5)); - Iterator i = sm.keySet().iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(m2, k); - k = (Integer)(i.next()); - assertEquals(m3, k); - assertFalse(i.hasNext()); - Iterator j = sm.keySet().iterator(); - j.next(); - j.remove(); - assertFalse(map.containsKey(m2)); - assertEquals(4, map.size()); - assertEquals(1, sm.size()); - assertEquals(m3, sm.firstKey()); - assertEquals(m3, sm.lastKey()); - assertEquals("C", sm.remove(m3)); - assertTrue(sm.isEmpty()); - assertEquals(3, map.size()); - } - - public void testDescendingSubMapContents2() { - ConcurrentNavigableMap map = dmap5(); - SortedMap sm = map.subMap(m2, m3); - assertEquals(1, sm.size()); - assertEquals(m2, sm.firstKey()); - assertEquals(m2, sm.lastKey()); - assertFalse(sm.containsKey(m1)); - assertTrue(sm.containsKey(m2)); - assertFalse(sm.containsKey(m3)); - assertFalse(sm.containsKey(m4)); - assertFalse(sm.containsKey(m5)); - Iterator i = sm.keySet().iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(m2, k); - assertFalse(i.hasNext()); - Iterator j = sm.keySet().iterator(); - j.next(); - j.remove(); - assertFalse(map.containsKey(m2)); - assertEquals(4, map.size()); - assertEquals(0, sm.size()); - assertTrue(sm.isEmpty()); - assertSame(sm.remove(m3), null); - assertEquals(4, map.size()); - } - - /** - * headMap returns map with keys in requested range - */ - public void testDescendingHeadMapContents() { - ConcurrentNavigableMap map = dmap5(); - SortedMap sm = map.headMap(m4); - assertTrue(sm.containsKey(m1)); - assertTrue(sm.containsKey(m2)); - assertTrue(sm.containsKey(m3)); - assertFalse(sm.containsKey(m4)); - assertFalse(sm.containsKey(m5)); - Iterator i = sm.keySet().iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(m1, k); - k = (Integer)(i.next()); - assertEquals(m2, k); - k = (Integer)(i.next()); - assertEquals(m3, k); - assertFalse(i.hasNext()); - sm.clear(); - assertTrue(sm.isEmpty()); - assertEquals(2, map.size()); - assertEquals(m4, map.firstKey()); - } - - /** - * headMap returns map with keys in requested range - */ - public void testDescendingTailMapContents() { - ConcurrentNavigableMap map = dmap5(); - SortedMap sm = map.tailMap(m2); - assertFalse(sm.containsKey(m1)); - assertTrue(sm.containsKey(m2)); - assertTrue(sm.containsKey(m3)); - assertTrue(sm.containsKey(m4)); - assertTrue(sm.containsKey(m5)); - Iterator i = sm.keySet().iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(m2, k); - k = (Integer)(i.next()); - assertEquals(m3, k); - k = (Integer)(i.next()); - assertEquals(m4, k); - k = (Integer)(i.next()); - assertEquals(m5, k); - assertFalse(i.hasNext()); - - Iterator ei = sm.entrySet().iterator(); - Map.Entry e; - e = (Map.Entry)(ei.next()); - assertEquals(m2, e.getKey()); - assertEquals("B", e.getValue()); - e = (Map.Entry)(ei.next()); - assertEquals(m3, e.getKey()); - assertEquals("C", e.getValue()); - e = (Map.Entry)(ei.next()); - assertEquals(m4, e.getKey()); - assertEquals("D", e.getValue()); - e = (Map.Entry)(ei.next()); - assertEquals(m5, e.getKey()); - assertEquals("E", e.getValue()); - assertFalse(i.hasNext()); - - SortedMap ssm = sm.tailMap(m4); - assertEquals(m4, ssm.firstKey()); - assertEquals(m5, ssm.lastKey()); - assertEquals("D", ssm.remove(m4)); - assertEquals(1, ssm.size()); - assertEquals(3, sm.size()); - assertEquals(4, map.size()); - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/BTreeSet2Test.java b/src/test/java/org/mapdb/BTreeSet2Test.java deleted file mode 100644 index 1149bfe5e..000000000 --- a/src/test/java/org/mapdb/BTreeSet2Test.java +++ /dev/null @@ -1,983 +0,0 @@ -package org.mapdb;/* - /* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -import java.io.Serializable; -import java.util.*; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class BTreeSet2Test extends JSR166TestCase { -// public static void main(String[] args) { -// junit.textui.TestRunner.run(suite()); -// } -// public static Test suite() { -// return new TestSuite(BTreeSet2Test.class); -// } -// - static class MyReverseComparator implements Comparator,Serializable { - private static final long serialVersionUID = 6921783514838686569L; - - public int compare(Object x, Object y) { - return ((Comparable)y).compareTo(x); - } - } - - /** - * Returns a new set of given size containing consecutive - * Integers 0 ... n. - */ - private NavigableSet populatedSet(int n) { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(q.isEmpty()); - for (int i = n-1; i >= 0; i-=2) - assertTrue(q.add(new Integer(i))); - for (int i = (n & 1); i < n; i+=2) - assertTrue(q.add(new Integer(i))); - assertFalse(q.isEmpty()); - assertEquals(n, q.size()); - return q; - } - - /** - * Returns a new set of first 5 ints. - */ - private NavigableSet set5() { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(q.isEmpty()); - q.add(one); - q.add(two); - q.add(three); - q.add(four); - q.add(five); - assertEquals(5, q.size()); - return q; - } - - /** - * A new set has unbounded capacity - */ - public void testConstructor1() { - assertEquals(0, DBMaker.newMemoryDB().make().getTreeSet("test").size()); - } - -// /** -// * Initializing from null Collection throws NPE -// */ -// public void testConstructor3() { -// try { -// NavigableSet q = new NavigableSet((Collection)null); -// shouldThrow(); -// } catch (NullPointerException success) {} -// } -// -// /** -// * Initializing from Collection of null elements throws NPE -// */ -// public void testConstructor4() { -// try { -// Integer[] ints = new Integer[SIZE]; -// NavigableSet q = new NavigableSet(Arrays.asList(ints)); -// shouldThrow(); -// } catch (NullPointerException success) {} -// } -// -// /** -// * Initializing from Collection with some null elements throws NPE -// */ -// public void testConstructor5() { -// try { -// Integer[] ints = new Integer[SIZE]; -// for (int i = 0; i < SIZE-1; ++i) -// ints[i] = new Integer(i); -// NavigableSet q = new NavigableSet(Arrays.asList(ints)); -// shouldThrow(); -// } catch (NullPointerException success) {} -// } -// -// /** -// * Set contains all elements of collection used to initialize -// */ -// public void testConstructor6() { -// Integer[] ints = new Integer[SIZE]; -// for (int i = 0; i < SIZE; ++i) -// ints[i] = new Integer(i); -// NavigableSet q = new NavigableSet(Arrays.asList(ints)); -// for (int i = 0; i < SIZE; ++i) -// assertEquals(ints[i], q.pollFirst()); -// } - - /** - * The comparator used in constructor is used - */ - public void testConstructor7() { - MyReverseComparator cmp = new MyReverseComparator(); - NavigableSet q = - DBMaker.newMemoryDB().make().createTreeSet("test").comparator(cmp).make(); - assertEquals(cmp, q.comparator()); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE; ++i) - ints[i] = new Integer(i); - q.addAll(Arrays.asList(ints)); - for (int i = SIZE-1; i >= 0; --i) - assertEquals(ints[i], q.pollFirst()); - } - - /** - * isEmpty is true before add, false after - */ - public void testEmpty() { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(q.isEmpty()); - q.add(new Integer(1)); - assertFalse(q.isEmpty()); - q.add(new Integer(2)); - q.pollFirst(); - q.pollFirst(); - assertTrue(q.isEmpty()); - } - - /** - * size changes when elements added and removed - */ - public void testSize() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertEquals(SIZE-i, q.size()); - q.pollFirst(); - } - for (int i = 0; i < SIZE; ++i) { - assertEquals(i, q.size()); - q.add(new Integer(i)); - } - } - - /** - * add(null) throws NPE - */ - public void testAddNull() { - try { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - q.add(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Add of comparable element succeeds - */ - public void testAdd() { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(q.add(zero)); - assertTrue(q.add(one)); - } - - /** - * Add of duplicate element fails - */ - public void testAddDup() { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(q.add(zero)); - assertFalse(q.add(zero)); - } - - /** - * Add of non-Comparable throws CCE - */ - public void testAddNonComparable() { - try { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - q.add(new Object()); - q.add(new Object()); - q.add(new Object()); - shouldThrow(); - } catch (ClassCastException success) {} - } - - /** - * addAll(null) throws NPE - */ - public void testAddAll1() { - try { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - q.addAll(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with null elements throws NPE - */ - public void testAddAll2() { - try { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - Integer[] ints = new Integer[SIZE]; - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with any null elements throws NPE after - * possibly adding some elements - */ - public void testAddAll3() { - try { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i); - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Set contains all elements of successful addAll - */ - public void testAddAll5() { - Integer[] empty = new Integer[0]; - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE; ++i) - ints[i] = new Integer(SIZE-1-i); - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertFalse(q.addAll(Arrays.asList(empty))); - assertTrue(q.addAll(Arrays.asList(ints))); - for (int i = 0; i < SIZE; ++i) - assertEquals(i, q.pollFirst()); - } - - /** - * pollFirst succeeds unless empty - */ - public void testPollFirst() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertEquals(i, q.pollFirst()); - } - assertNull(q.pollFirst()); - } - - /** - * pollLast succeeds unless empty - */ - public void testPollLast() { - NavigableSet q = populatedSet(SIZE); - for (int i = SIZE-1; i >= 0; --i) { - assertEquals(i, q.pollLast()); - } - assertNull(q.pollFirst()); - } - - /** - * remove(x) removes x and returns true if present - */ - public void testRemoveElement() { - NavigableSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { - assertTrue(q.contains(i)); - assertTrue(q.remove(i)); - assertFalse(q.contains(i)); - assertTrue(q.contains(i-1)); - } - for (int i = 0; i < SIZE; i+=2) { - assertTrue(q.contains(i)); - assertTrue(q.remove(i)); - assertFalse(q.contains(i)); - assertFalse(q.remove(i + 1)); - assertFalse(q.contains(i + 1)); - } - assertTrue(q.isEmpty()); - } - - /** - * contains(x) reports true when elements added but not yet removed - */ - public void testContains() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.contains(new Integer(i))); - q.pollFirst(); - assertFalse(q.contains(new Integer(i))); - } - } - - /** - * clear removes all elements - */ - public void testClear() { - NavigableSet q = populatedSet(SIZE); - q.clear(); - assertTrue(q.isEmpty()); - assertEquals(0, q.size()); - q.add(new Integer(1)); - assertFalse(q.isEmpty()); - q.clear(); - assertTrue(q.isEmpty()); - } - - /** - * containsAll(c) is true when c contains a subset of elements - */ - public void testContainsAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = DBMaker.newMemoryDB().make().getTreeSet("test"); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.containsAll(p)); - assertFalse(p.containsAll(q)); - p.add(new Integer(i)); - } - assertTrue(p.containsAll(q)); - } - - /** - * retainAll(c) retains only those elements of c and reports true if changed - */ - public void testRetainAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - boolean changed = q.retainAll(p); - if (i == 0) - assertFalse(changed); - else - assertTrue(changed); - - assertTrue(q.containsAll(p)); - assertEquals(SIZE-i, q.size()); - p.pollFirst(); - } - } - - /** - * removeAll(c) removes only those elements of c and reports true if changed - */ - public void testRemoveAll() { - for (int i = 1; i < SIZE; ++i) { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(i); - assertTrue(q.removeAll(p)); - assertEquals(SIZE-i, q.size()); - for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); - } - } - } - - /** - * lower returns preceding element - */ - public void testLower() { - NavigableSet q = set5(); - Object e1 = q.lower(three); - assertEquals(two, e1); - - Object e2 = q.lower(six); - assertEquals(five, e2); - - Object e3 = q.lower(one); - assertNull(e3); - - Object e4 = q.lower(zero); - assertNull(e4); - } - - /** - * higher returns next element - */ - public void testHigher() { - NavigableSet q = set5(); - Object e1 = q.higher(three); - assertEquals(four, e1); - - Object e2 = q.higher(zero); - assertEquals(one, e2); - - Object e3 = q.higher(five); - assertNull(e3); - - Object e4 = q.higher(six); - assertNull(e4); - } - - /** - * floor returns preceding element - */ - public void testFloor() { - NavigableSet q = set5(); - Object e1 = q.floor(three); - assertEquals(three, e1); - - Object e2 = q.floor(six); - assertEquals(five, e2); - - Object e3 = q.floor(one); - assertEquals(one, e3); - - Object e4 = q.floor(zero); - assertNull(e4); - } - - /** - * ceiling returns next element - */ - public void testCeiling() { - NavigableSet q = set5(); - Object e1 = q.ceiling(three); - assertEquals(three, e1); - - Object e2 = q.ceiling(zero); - assertEquals(one, e2); - - Object e3 = q.ceiling(five); - assertEquals(five, e3); - - Object e4 = q.ceiling(six); - assertNull(e4); - } - - /** - * toArray contains all elements in sorted order - */ - public void testToArray() { - NavigableSet q = populatedSet(SIZE); - Object[] o = q.toArray(); - for (int i = 0; i < o.length; i++) - assertSame(o[i], q.pollFirst()); - } - - /** - * toArray(a) contains all elements in sorted order - */ - public void testToArray2() { - NavigableSet q = populatedSet(SIZE); - Integer[] ints = new Integer[SIZE]; - assertSame(ints, q.toArray(ints)); - for (int i = 0; i < ints.length; i++) - assertSame(ints[i], q.pollFirst()); - } - - /** - * iterator iterates through all elements - */ - public void testIterator() { - NavigableSet q = populatedSet(SIZE); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(i, SIZE); - } - - /** - * iterator of empty set has no elements - */ - public void testEmptyIterator() { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(0, i); - } - - /** - * iterator.remove removes current element - */ - public void testIteratorRemove() { - final NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - q.add(new Integer(2)); - q.add(new Integer(1)); - q.add(new Integer(3)); - - Iterator it = q.iterator(); - it.next(); - it.remove(); - - it = q.iterator(); - assertEquals(it.next(), new Integer(2)); - assertEquals(it.next(), new Integer(3)); - assertFalse(it.hasNext()); - } - - /** - * toString contains toStrings of elements - */ - public void testToString() { - NavigableSet q = populatedSet(SIZE); - String s = q.toString(); - for (int i = 0; i < SIZE; ++i) { - assertTrue(s.contains(String.valueOf(i))); - } - } - -// /** -// * A deserialized serialized set has same elements -// */ -// public void testSerialization() throws Exception { -// NavigableSet x = populatedSet(SIZE); -// NavigableSet y = serialClone(x); -// -// assertNotSame(x, y); -// assertEquals(x.size(), y.size()); -// assertEquals(x, y); -// assertEquals(y, x); -// while (!x.isEmpty()) { -// assertFalse(y.isEmpty()); -// assertEquals(x.pollFirst(), y.pollFirst()); -// } -// assertTrue(y.isEmpty()); -// } - - /** - * subSet returns set with keys in requested range - */ - public void testSubSetContents() { - NavigableSet set = set5(); - SortedSet sm = set.subSet(two, four); - assertEquals(two, sm.first()); - assertEquals(three, sm.last()); - assertEquals(2, sm.size()); - assertFalse(sm.contains(one)); - assertTrue(sm.contains(two)); - assertTrue(sm.contains(three)); - assertFalse(sm.contains(four)); - assertFalse(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - assertFalse(i.hasNext()); - Iterator j = sm.iterator(); - j.next(); - j.remove(); - assertFalse(set.contains(two)); - assertEquals(4, set.size()); - assertEquals(1, sm.size()); - assertEquals(three, sm.first()); - assertEquals(three, sm.last()); - assertTrue(sm.remove(three)); - assertTrue(sm.isEmpty()); - assertEquals(3, set.size()); - } - - public void testSubSetContents2() { - NavigableSet set = set5(); - SortedSet sm = set.subSet(two, three); - assertEquals(1, sm.size()); - assertEquals(two, sm.first()); - assertEquals(two, sm.last()); - assertFalse(sm.contains(one)); - assertTrue(sm.contains(two)); - assertFalse(sm.contains(three)); - assertFalse(sm.contains(four)); - assertFalse(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - assertFalse(i.hasNext()); - Iterator j = sm.iterator(); - j.next(); - j.remove(); - assertFalse(set.contains(two)); - assertEquals(4, set.size()); - assertEquals(0, sm.size()); - assertTrue(sm.isEmpty()); - assertFalse(sm.remove(three)); - assertEquals(4, set.size()); - } - - /** - * headSet returns set with keys in requested range - */ - public void testHeadSetContents() { - NavigableSet set = set5(); - SortedSet sm = set.headSet(four); - assertTrue(sm.contains(one)); - assertTrue(sm.contains(two)); - assertTrue(sm.contains(three)); - assertFalse(sm.contains(four)); - assertFalse(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(one, k); - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - assertFalse(i.hasNext()); - sm.clear(); - assertTrue(sm.isEmpty()); - assertEquals(2, set.size()); - assertEquals(four, set.first()); - } - - /** - * tailSet returns set with keys in requested range - */ - public void testTailSetContents() { - NavigableSet set = set5(); - SortedSet sm = set.tailSet(two); - assertFalse(sm.contains(one)); - assertTrue(sm.contains(two)); - assertTrue(sm.contains(three)); - assertTrue(sm.contains(four)); - assertTrue(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - k = (Integer)(i.next()); - assertEquals(four, k); - k = (Integer)(i.next()); - assertEquals(five, k); - assertFalse(i.hasNext()); - - SortedSet ssm = sm.tailSet(four); - assertEquals(four, ssm.first()); - assertEquals(five, ssm.last()); - assertTrue(ssm.remove(four)); - assertEquals(1, ssm.size()); - assertEquals(3, sm.size()); - assertEquals(4, set.size()); - } - - Random rnd = new Random(666); - - final boolean expensiveTests = true; - - /** - * Subsets of subsets subdivide correctly - */ - public void testRecursiveSubSets() throws Exception { - int setSize = expensiveTests ? 1000 : 100; - Class cl = NavigableSet.class; - - NavigableSet set = newSet(cl); - BitSet bs = new BitSet(setSize); - - populate(set, setSize, bs); - check(set, 0, setSize - 1, true, bs); - check(set.descendingSet(), 0, setSize - 1, false, bs); - - mutateSet(set, 0, setSize - 1, bs); - check(set, 0, setSize - 1, true, bs); - check(set.descendingSet(), 0, setSize - 1, false, bs); - - bashSubSet(set.subSet(0, true, setSize, false), - 0, setSize - 1, true, bs); - } - - /** - * addAll is idempotent - */ - public void testAddAll_idempotent() throws Exception { - Set x = populatedSet(SIZE); - Set y = DBMaker.newMemoryDB().make().getTreeSet("test"); - y.addAll(x); - assertEquals(x, y); - assertEquals(y, x); - } - - static NavigableSet newSet(Class cl) throws Exception { - NavigableSet result = DBMaker.newMemoryDB().make().getTreeSet("test"); - //(NavigableSet) cl.newInstance(); - assertEquals(0, result.size()); - assertFalse(result.iterator().hasNext()); - return result; - } - - void populate(NavigableSet set, int limit, BitSet bs) { - for (int i = 0, n = 2 * limit / 3; i < n; i++) { - int element = rnd.nextInt(limit); - put(set, element, bs); - } - } - - void mutateSet(NavigableSet set, int min, int max, BitSet bs) { - int size = set.size(); - int rangeSize = max - min + 1; - - // Remove a bunch of entries directly - for (int i = 0, n = rangeSize / 2; i < n; i++) { - remove(set, min - 5 + rnd.nextInt(rangeSize + 10), bs); - } - - // Remove a bunch of entries with iterator - for (Iterator it = set.iterator(); it.hasNext(); ) { - if (rnd.nextBoolean()) { - bs.clear(it.next()); - it.remove(); - } - } - - // Add entries till we're back to original size - while (set.size() < size) { - int element = min + rnd.nextInt(rangeSize); - assertTrue(element >= min && element<= max); - put(set, element, bs); - } - } - - void mutateSubSet(NavigableSet set, int min, int max, - BitSet bs) { - int size = set.size(); - int rangeSize = max - min + 1; - - // Remove a bunch of entries directly - for (int i = 0, n = rangeSize / 2; i < n; i++) { - remove(set, min - 5 + rnd.nextInt(rangeSize + 10), bs); - } - - // Remove a bunch of entries with iterator - for (Iterator it = set.iterator(); it.hasNext(); ) { - if (rnd.nextBoolean()) { - bs.clear(it.next()); - it.remove(); - } - } - - // Add entries till we're back to original size - while (set.size() < size) { - int element = min - 5 + rnd.nextInt(rangeSize + 10); - if (element >= min && element<= max) { - put(set, element, bs); - } else { - try { - set.add(element); - shouldThrow(); - } catch (IllegalArgumentException success) {} - } - } - } - - void put(NavigableSet set, int element, BitSet bs) { - if (set.add(element)) - bs.set(element); - } - - void remove(NavigableSet set, int element, BitSet bs) { - if (set.remove(element)) - bs.clear(element); - } - - void bashSubSet(NavigableSet set, - int min, int max, boolean ascending, - BitSet bs) { - check(set, min, max, ascending, bs); - check(set.descendingSet(), min, max, !ascending, bs); - - mutateSubSet(set, min, max, bs); - check(set, min, max, ascending, bs); - check(set.descendingSet(), min, max, !ascending, bs); - - // Recurse - if (max - min < 2) - return; - int midPoint = (min + max) / 2; - - // headSet - pick direction and endpoint inclusion randomly - boolean incl = rnd.nextBoolean(); - NavigableSet hm = set.headSet(midPoint, incl); - if (ascending) { - if (rnd.nextBoolean()) - bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true, bs); - else - bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1), - false, bs); - } else { - if (rnd.nextBoolean()) - bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false, bs); - else - bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max, - true, bs); - } - - // tailSet - pick direction and endpoint inclusion randomly - incl = rnd.nextBoolean(); - NavigableSet tm = set.tailSet(midPoint,incl); - if (ascending) { - if (rnd.nextBoolean()) - bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true, bs); - else - bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max, - false, bs); - } else { - if (rnd.nextBoolean()) { - bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false, bs); - } else { - bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1), - true, bs); - } - } - - // subSet - pick direction and endpoint inclusion randomly - int rangeSize = max - min + 1; - int[] endpoints = new int[2]; - endpoints[0] = min + rnd.nextInt(rangeSize); - endpoints[1] = min + rnd.nextInt(rangeSize); - Arrays.sort(endpoints); - boolean lowIncl = rnd.nextBoolean(); - boolean highIncl = rnd.nextBoolean(); - if (ascending) { - NavigableSet sm = set.subSet( - endpoints[0], lowIncl, endpoints[1], highIncl); - if (rnd.nextBoolean()) - bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1), - endpoints[1] - (highIncl ? 0 : 1), true, bs); - else - bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1), - endpoints[1] - (highIncl ? 0 : 1), false, bs); - } else { - NavigableSet sm = set.subSet( - endpoints[1], highIncl, endpoints[0], lowIncl); - if (rnd.nextBoolean()) - bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1), - endpoints[1] - (highIncl ? 0 : 1), false, bs); - else - bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1), - endpoints[1] - (highIncl ? 0 : 1), true, bs); - } - } - - /** - * min and max are both inclusive. If max < min, interval is empty. - */ - void check(NavigableSet set, - final int min, final int max, final boolean ascending, - final BitSet bs) { - class ReferenceSet { - int lower(int element) { - return ascending ? - lowerAscending(element) : higherAscending(element); - } - int floor(int element) { - return ascending ? - floorAscending(element) : ceilingAscending(element); - } - int ceiling(int element) { - return ascending ? - ceilingAscending(element) : floorAscending(element); - } - int higher(int element) { - return ascending ? - higherAscending(element) : lowerAscending(element); - } - int first() { - return ascending ? firstAscending() : lastAscending(); - } - int last() { - return ascending ? lastAscending() : firstAscending(); - } - int lowerAscending(int element) { - return floorAscending(element - 1); - } - int floorAscending(int element) { - if (element < min) - return -1; - else if (element > max) - element = max; - - // BitSet should support this! Test would run much faster - while (element >= min) { - if (bs.get(element)) - return element; - element--; - } - return -1; - } - int ceilingAscending(int element) { - if (element < min) - element = min; - else if (element > max) - return -1; - int result = bs.nextSetBit(element); - return result > max ? -1 : result; - } - int higherAscending(int element) { - return ceilingAscending(element + 1); - } - private int firstAscending() { - int result = ceilingAscending(min); - return result > max ? -1 : result; - } - private int lastAscending() { - int result = floorAscending(max); - return result < min ? -1 : result; - } - } - ReferenceSet rs = new ReferenceSet(); - - // Test contents using containsElement - int size = 0; - for (int i = min; i <= max; i++) { - boolean bsContainsI = bs.get(i); - assertEquals(bsContainsI, set.contains(i)); - if (bsContainsI) - size++; - } - assertEquals(size, set.size()); - - // Test contents using contains elementSet iterator - int size2 = 0; - int previousElement = -1; - for (int element : set) { - assertTrue(bs.get(element)); - size2++; - assertTrue(previousElement < 0 || (ascending ? - element - previousElement > 0 : element - previousElement < 0)); - previousElement = element; - } - assertEquals(size2, size); - - // Test navigation ops - for (int element = min - 1; element <= max + 1; element++) { - assertEq(set.lower(element), rs.lower(element)); - assertEq(set.floor(element), rs.floor(element)); - assertEq(set.higher(element), rs.higher(element)); - assertEq(set.ceiling(element), rs.ceiling(element)); - } - - // Test extrema - if (set.size() != 0) { - assertEq(set.first(), rs.first()); - assertEq(set.last(), rs.last()); - } else { - assertEq(rs.first(), -1); - assertEq(rs.last(), -1); - try { - set.first(); - shouldThrow(); - } catch (NoSuchElementException success) {} - try { - set.last(); - shouldThrow(); - } catch (NoSuchElementException success) {} - } - } - - static void assertEq(Integer i, int j) { - if (i == null) - assertEquals(j, -1); - else - assertEquals((int) i, j); - } - - static boolean eq(Integer i, int j) { - return i == null ? j == -1 : i == j; - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/BTreeSet3Test.java b/src/test/java/org/mapdb/BTreeSet3Test.java deleted file mode 100644 index 18541331c..000000000 --- a/src/test/java/org/mapdb/BTreeSet3Test.java +++ /dev/null @@ -1,1116 +0,0 @@ -package org.mapdb; - -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -import junit.framework.Test; -import junit.framework.TestSuite; - -import java.util.*; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class BTreeSet3Test extends JSR166TestCase { - - static class MyReverseComparator implements Comparator { - public int compare(Object x, Object y) { - return ((Comparable)y).compareTo(x); - } - } - - /** - * Returns a new set of given size containing consecutive - * Integers 0 ... n. - */ - private NavigableSet populatedSet(int n) { - NavigableSet q = - DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(q.isEmpty()); - - for (int i = n-1; i >= 0; i-=2) - assertTrue(q.add(new Integer(i))); - for (int i = (n & 1); i < n; i+=2) - assertTrue(q.add(new Integer(i))); - assertTrue(q.add(new Integer(-n))); - assertTrue(q.add(new Integer(n))); - NavigableSet s = q.subSet(new Integer(0), true, new Integer(n), false); - assertFalse(s.isEmpty()); - assertEquals(n, s.size()); - return s; - } - - /** - * Returns a new set of first 5 ints. - */ - private NavigableSet set5() { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(q.isEmpty()); - q.add(one); - q.add(two); - q.add(three); - q.add(four); - q.add(five); - q.add(zero); - q.add(seven); - NavigableSet s = q.subSet(one, true, seven, false); - assertEquals(5, s.size()); - return s; - } - - /** - * Returns a new set of first 5 negative ints. - */ - private NavigableSet dset5() { - NavigableSet q = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(q.isEmpty()); - q.add(m1); - q.add(m2); - q.add(m3); - q.add(m4); - q.add(m5); - NavigableSet s = q.descendingSet(); - assertEquals(5, s.size()); - return s; - } - - private static NavigableSet set0() { - NavigableSet set = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(set.isEmpty()); - return set.tailSet(m1, true); - } - - private static NavigableSet dset0() { - NavigableSet set = DBMaker.newMemoryDB().make().getTreeSet("test"); - assertTrue(set.isEmpty()); - return set; - } - - /** - * A new set has unbounded capacity - */ - public void testConstructor1() { - assertEquals(0, set0().size()); - } - - /** - * isEmpty is true before add, false after - */ - public void testEmpty() { - NavigableSet q = set0(); - assertTrue(q.isEmpty()); - q.add(new Integer(1)); - assertFalse(q.isEmpty()); - q.add(new Integer(2)); - q.pollFirst(); - q.pollFirst(); - assertTrue(q.isEmpty()); - } - - /** - * size changes when elements added and removed - */ - public void testSize() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertEquals(SIZE-i, q.size()); - q.pollFirst(); - } - for (int i = 0; i < SIZE; ++i) { - assertEquals(i, q.size()); - q.add(new Integer(i)); - } - } - - /** - * add(null) throws NPE - */ - public void testAddNull() { - try { - NavigableSet q = set0(); - q.add(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Add of comparable element succeeds - */ - public void testAdd() { - NavigableSet q = set0(); - assertTrue(q.add(six)); - } - - /** - * Add of duplicate element fails - */ - public void testAddDup() { - NavigableSet q = set0(); - assertTrue(q.add(six)); - assertFalse(q.add(six)); - } - - /** - * Add of non-Comparable throws CCE - */ - public void testAddNonComparable() { - try { - NavigableSet q = set0(); - q.add(new Object()); - q.add(new Object()); - q.add(new Object()); - shouldThrow(); - } catch (ClassCastException success) {} - } - - /** - * addAll(null) throws NPE - */ - public void testAddAll1() { - try { - NavigableSet q = set0(); - q.addAll(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with null elements throws NPE - */ - public void testAddAll2() { - try { - NavigableSet q = set0(); - Integer[] ints = new Integer[SIZE]; - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with any null elements throws NPE after - * possibly adding some elements - */ - public void testAddAll3() { - try { - NavigableSet q = set0(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i+SIZE); - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Set contains all elements of successful addAll - */ - public void testAddAll5() { - Integer[] empty = new Integer[0]; - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE; ++i) - ints[i] = new Integer(SIZE-1- i); - NavigableSet q = set0(); - assertFalse(q.addAll(Arrays.asList(empty))); - assertTrue(q.addAll(Arrays.asList(ints))); - for (int i = 0; i < SIZE; ++i) - assertEquals(new Integer(i), q.pollFirst()); - } - - /** - * poll succeeds unless empty - */ - public void testPoll() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertEquals(i, q.pollFirst()); - } - assertNull(q.pollFirst()); - } - - /** - * remove(x) removes x and returns true if present - */ - public void testRemoveElement() { - NavigableSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { - assertTrue(q.contains(i)); - assertTrue(q.remove(i)); - assertFalse(q.contains(i)); - assertTrue(q.contains(i-1)); - } - for (int i = 0; i < SIZE; i+=2) { - assertTrue(q.contains(i)); - assertTrue(q.remove(i)); - assertFalse(q.contains(i)); - assertFalse(q.remove(i+1)); - assertFalse(q.contains(i+1)); - } - assertTrue(q.isEmpty()); - } - - /** - * contains(x) reports true when elements added but not yet removed - */ - public void testContains() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.contains(new Integer(i))); - q.pollFirst(); - assertFalse(q.contains(new Integer(i))); - } - } - - /** - * clear removes all elements - */ - public void testClear() { - NavigableSet q = populatedSet(SIZE); - q.clear(); - assertTrue(q.isEmpty()); - assertEquals(0, q.size()); - q.add(new Integer(1)); - assertFalse(q.isEmpty()); - q.clear(); - assertTrue(q.isEmpty()); - } - - /** - * containsAll(c) is true when c contains a subset of elements - */ - public void testContainsAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = set0(); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.containsAll(p)); - assertFalse(p.containsAll(q)); - p.add(new Integer(i)); - } - assertTrue(p.containsAll(q)); - } - - /** - * retainAll(c) retains only those elements of c and reports true if changed - */ - public void testRetainAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - boolean changed = q.retainAll(p); - if (i == 0) - assertFalse(changed); - else - assertTrue(changed); - - assertTrue(q.containsAll(p)); - assertEquals(SIZE-i, q.size()); - p.pollFirst(); - } - } - - /** - * removeAll(c) removes only those elements of c and reports true if changed - */ - public void testRemoveAll() { - for (int i = 1; i < SIZE; ++i) { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(i); - assertTrue(q.removeAll(p)); - assertEquals(SIZE-i, q.size()); - for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); - } - } - } - - /** - * lower returns preceding element - */ - public void testLower() { - NavigableSet q = set5(); - Object e1 = q.lower(three); - assertEquals(two, e1); - - Object e2 = q.lower(six); - assertEquals(five, e2); - - Object e3 = q.lower(one); - assertNull(e3); - - Object e4 = q.lower(zero); - assertNull(e4); - } - - /** - * higher returns next element - */ - public void testHigher() { - NavigableSet q = set5(); - Object e1 = q.higher(three); - assertEquals(four, e1); - - Object e2 = q.higher(zero); - assertEquals(one, e2); - - Object e3 = q.higher(five); - assertNull(e3); - - Object e4 = q.higher(six); - assertNull(e4); - } - - /** - * floor returns preceding element - */ - public void testFloor() { - NavigableSet q = set5(); - Object e1 = q.floor(three); - assertEquals(three, e1); - - Object e2 = q.floor(six); - assertEquals(five, e2); - - Object e3 = q.floor(one); - assertEquals(one, e3); - - Object e4 = q.floor(zero); - assertNull(e4); - } - - /** - * ceiling returns next element - */ - public void testCeiling() { - NavigableSet q = set5(); - Object e1 = q.ceiling(three); - assertEquals(three, e1); - - Object e2 = q.ceiling(zero); - assertEquals(one, e2); - - Object e3 = q.ceiling(five); - assertEquals(five, e3); - - Object e4 = q.ceiling(six); - assertNull(e4); - } - - /** - * toArray contains all elements in sorted order - */ - public void testToArray() { - NavigableSet q = populatedSet(SIZE); - Object[] o = q.toArray(); - for (int i = 0; i < o.length; i++) - assertSame(o[i], q.pollFirst()); - } - - /** - * toArray(a) contains all elements in sorted order - */ - public void testToArray2() { - NavigableSet q = populatedSet(SIZE); - Integer[] ints = new Integer[SIZE]; - Integer[] array = q.toArray(ints); - assertSame(ints, array); - for (int i = 0; i < ints.length; i++) - assertSame(ints[i], q.pollFirst()); - } - - /** - * iterator iterates through all elements - */ - public void testIterator() { - NavigableSet q = populatedSet(SIZE); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(i, SIZE); - } - - /** - * iterator of empty set has no elements - */ - public void testEmptyIterator() { - NavigableSet q = set0(); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(0, i); - } - - /** - * iterator.remove removes current element - */ - public void testIteratorRemove() { - final NavigableSet q = set0(); - q.add(new Integer(2)); - q.add(new Integer(1)); - q.add(new Integer(3)); - - Iterator it = q.iterator(); - it.next(); - it.remove(); - - it = q.iterator(); - assertEquals(it.next(), new Integer(2)); - assertEquals(it.next(), new Integer(3)); - assertFalse(it.hasNext()); - } - - /** - * toString contains toStrings of elements - */ - public void testToString() { - NavigableSet q = populatedSet(SIZE); - String s = q.toString(); - for (int i = 0; i < SIZE; ++i) { - assertTrue(s.contains(String.valueOf(i))); - } - } - -// /** -// * A deserialized serialized set has same elements -// */ -// public void testSerialization() throws Exception { -// NavigableSet x = populatedSet(SIZE); -// NavigableSet y = serialClone(x); -// -// assertNotSame(y, x); -// assertEquals(x.size(), y.size()); -// assertEquals(x, y); -// assertEquals(y, x); -// while (!x.isEmpty()) { -// assertFalse(y.isEmpty()); -// assertEquals(x.pollFirst(), y.pollFirst()); -// } -// assertTrue(y.isEmpty()); -// } -// - /** - * subSet returns set with keys in requested range - */ - public void testSubSetContents() { - NavigableSet set = set5(); - SortedSet sm = set.subSet(two, four); - assertEquals(two, sm.first()); - assertEquals(three, sm.last()); - assertEquals(2, sm.size()); - assertFalse(sm.contains(one)); - assertTrue(sm.contains(two)); - assertTrue(sm.contains(three)); - assertFalse(sm.contains(four)); - assertFalse(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - assertFalse(i.hasNext()); - Iterator j = sm.iterator(); - j.next(); - j.remove(); - assertFalse(set.contains(two)); - assertEquals(4, set.size()); - assertEquals(1, sm.size()); - assertEquals(three, sm.first()); - assertEquals(three, sm.last()); - assertTrue(sm.remove(three)); - assertTrue(sm.isEmpty()); - assertEquals(3, set.size()); - } - - public void testSubSetContents2() { - NavigableSet set = set5(); - SortedSet sm = set.subSet(two, three); - assertEquals(1, sm.size()); - assertEquals(two, sm.first()); - assertEquals(two, sm.last()); - assertFalse(sm.contains(one)); - assertTrue(sm.contains(two)); - assertFalse(sm.contains(three)); - assertFalse(sm.contains(four)); - assertFalse(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - assertFalse(i.hasNext()); - Iterator j = sm.iterator(); - j.next(); - j.remove(); - assertFalse(set.contains(two)); - assertEquals(4, set.size()); - assertEquals(0, sm.size()); - assertTrue(sm.isEmpty()); - assertFalse(sm.remove(three)); - assertEquals(4, set.size()); - } - - /** - * headSet returns set with keys in requested range - */ - public void testHeadSetContents() { - NavigableSet set = set5(); - SortedSet sm = set.headSet(four); - assertTrue(sm.contains(one)); - assertTrue(sm.contains(two)); - assertTrue(sm.contains(three)); - assertFalse(sm.contains(four)); - assertFalse(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(one, k); - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - assertFalse(i.hasNext()); - sm.clear(); - assertTrue(sm.isEmpty()); - assertEquals(2, set.size()); - assertEquals(four, set.first()); - } - - /** - * tailSet returns set with keys in requested range - */ - public void testTailSetContents() { - NavigableSet set = set5(); - SortedSet sm = set.tailSet(two); - assertFalse(sm.contains(one)); - assertTrue(sm.contains(two)); - assertTrue(sm.contains(three)); - assertTrue(sm.contains(four)); - assertTrue(sm.contains(five)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(two, k); - k = (Integer)(i.next()); - assertEquals(three, k); - k = (Integer)(i.next()); - assertEquals(four, k); - k = (Integer)(i.next()); - assertEquals(five, k); - assertFalse(i.hasNext()); - - SortedSet ssm = sm.tailSet(four); - assertEquals(four, ssm.first()); - assertEquals(five, ssm.last()); - assertTrue(ssm.remove(four)); - assertEquals(1, ssm.size()); - assertEquals(3, sm.size()); - assertEquals(4, set.size()); - } - - /** - * size changes when elements added and removed - */ - public void testDescendingSize() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertEquals(SIZE-i, q.size()); - q.pollFirst(); - } - for (int i = 0; i < SIZE; ++i) { - assertEquals(i, q.size()); - q.add(new Integer(i)); - } - } - - /** - * add(null) throws NPE - */ - public void testDescendingAddNull() { - try { - NavigableSet q = dset0(); - q.add(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Add of comparable element succeeds - */ - public void testDescendingAdd() { - NavigableSet q = dset0(); - assertTrue(q.add(m6)); - } - - /** - * Add of duplicate element fails - */ - public void testDescendingAddDup() { - NavigableSet q = dset0(); - assertTrue(q.add(m6)); - assertFalse(q.add(m6)); - } - - /** - * Add of non-Comparable throws CCE - */ - public void testDescendingAddNonComparable() { - try { - NavigableSet q = dset0(); - q.add(new Object()); - q.add(new Object()); - q.add(new Object()); - shouldThrow(); - } catch (ClassCastException success) {} - } - - /** - * addAll(null) throws NPE - */ - public void testDescendingAddAll1() { - try { - NavigableSet q = dset0(); - q.addAll(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with null elements throws NPE - */ - public void testDescendingAddAll2() { - try { - NavigableSet q = dset0(); - Integer[] ints = new Integer[SIZE]; - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll of a collection with any null elements throws NPE after - * possibly adding some elements - */ - public void testDescendingAddAll3() { - try { - NavigableSet q = dset0(); - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) - ints[i] = new Integer(i+SIZE); - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * Set contains all elements of successful addAll - */ - public void testDescendingAddAll5() { - Integer[] empty = new Integer[0]; - Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE; ++i) - ints[i] = new Integer(SIZE-1- i); - NavigableSet q = dset0(); - assertFalse(q.addAll(Arrays.asList(empty))); - assertTrue(q.addAll(Arrays.asList(ints))); - for (int i = 0; i < SIZE; ++i) - assertEquals(new Integer(i), q.pollFirst()); - } - - /** - * poll succeeds unless empty - */ - public void testDescendingPoll() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertEquals(i, q.pollFirst()); - } - assertNull(q.pollFirst()); - } - - /** - * remove(x) removes x and returns true if present - */ - public void testDescendingRemoveElement() { - NavigableSet q = populatedSet(SIZE); - for (int i = 1; i < SIZE; i+=2) { - assertTrue(q.remove(new Integer(i))); - } - for (int i = 0; i < SIZE; i+=2) { - assertTrue(q.remove(new Integer(i))); - assertFalse(q.remove(new Integer(i+1))); - } - assertTrue(q.isEmpty()); - } - - /** - * contains(x) reports true when elements added but not yet removed - */ - public void testDescendingContains() { - NavigableSet q = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.contains(new Integer(i))); - q.pollFirst(); - assertFalse(q.contains(new Integer(i))); - } - } - - /** - * clear removes all elements - */ - public void testDescendingClear() { - NavigableSet q = populatedSet(SIZE); - q.clear(); - assertTrue(q.isEmpty()); - assertEquals(0, q.size()); - q.add(new Integer(1)); - assertFalse(q.isEmpty()); - q.clear(); - assertTrue(q.isEmpty()); - } - - /** - * containsAll(c) is true when c contains a subset of elements - */ - public void testDescendingContainsAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = dset0(); - for (int i = 0; i < SIZE; ++i) { - assertTrue(q.containsAll(p)); - assertFalse(p.containsAll(q)); - p.add(new Integer(i)); - } - assertTrue(p.containsAll(q)); - } - - /** - * retainAll(c) retains only those elements of c and reports true if changed - */ - public void testDescendingRetainAll() { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(SIZE); - for (int i = 0; i < SIZE; ++i) { - boolean changed = q.retainAll(p); - if (i == 0) - assertFalse(changed); - else - assertTrue(changed); - - assertTrue(q.containsAll(p)); - assertEquals(SIZE-i, q.size()); - p.pollFirst(); - } - } - - /** - * removeAll(c) removes only those elements of c and reports true if changed - */ - public void testDescendingRemoveAll() { - for (int i = 1; i < SIZE; ++i) { - NavigableSet q = populatedSet(SIZE); - NavigableSet p = populatedSet(i); - assertTrue(q.removeAll(p)); - assertEquals(SIZE-i, q.size()); - for (int j = 0; j < i; ++j) { - Integer I = (Integer)(p.pollFirst()); - assertFalse(q.contains(I)); - } - } - } - - /** - * lower returns preceding element - */ - public void testDescendingLower() { - NavigableSet q = dset5(); - Object e1 = q.lower(m3); - assertEquals(m2, e1); - - Object e2 = q.lower(m6); - assertEquals(m5, e2); - - Object e3 = q.lower(m1); - assertNull(e3); - - Object e4 = q.lower(zero); - assertNull(e4); - } - - /** - * higher returns next element - */ - public void testDescendingHigher() { - NavigableSet q = dset5(); - Object e1 = q.higher(m3); - assertEquals(m4, e1); - - Object e2 = q.higher(zero); - assertEquals(m1, e2); - - Object e3 = q.higher(m5); - assertNull(e3); - - Object e4 = q.higher(m6); - assertNull(e4); - } - - /** - * floor returns preceding element - */ - public void testDescendingFloor() { - NavigableSet q = dset5(); - Object e1 = q.floor(m3); - assertEquals(m3, e1); - - Object e2 = q.floor(m6); - assertEquals(m5, e2); - - Object e3 = q.floor(m1); - assertEquals(m1, e3); - - Object e4 = q.floor(zero); - assertNull(e4); - } - - /** - * ceiling returns next element - */ - public void testDescendingCeiling() { - NavigableSet q = dset5(); - Object e1 = q.ceiling(m3); - assertEquals(m3, e1); - - Object e2 = q.ceiling(zero); - assertEquals(m1, e2); - - Object e3 = q.ceiling(m5); - assertEquals(m5, e3); - - Object e4 = q.ceiling(m6); - assertNull(e4); - } - - /** - * toArray contains all elements - */ - public void testDescendingToArray() { - NavigableSet q = populatedSet(SIZE); - Object[] o = q.toArray(); - Arrays.sort(o); - for (int i = 0; i < o.length; i++) - assertEquals(o[i], q.pollFirst()); - } - - /** - * toArray(a) contains all elements - */ - public void testDescendingToArray2() { - NavigableSet q = populatedSet(SIZE); - Integer[] ints = new Integer[SIZE]; - assertSame(ints, q.toArray(ints)); - Arrays.sort(ints); - for (int i = 0; i < ints.length; i++) - assertEquals(ints[i], q.pollFirst()); - } - - /** - * iterator iterates through all elements - */ - public void testDescendingIterator() { - NavigableSet q = populatedSet(SIZE); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(i, SIZE); - } - - /** - * iterator of empty set has no elements - */ - public void testDescendingEmptyIterator() { - NavigableSet q = dset0(); - int i = 0; - Iterator it = q.iterator(); - while (it.hasNext()) { - assertTrue(q.contains(it.next())); - ++i; - } - assertEquals(0, i); - } - - /** - * iterator.remove removes current element - */ - public void testDescendingIteratorRemove() { - final NavigableSet q = dset0(); - q.add(new Integer(2)); - q.add(new Integer(1)); - q.add(new Integer(3)); - - Iterator it = q.iterator(); - it.next(); - it.remove(); - - it = q.iterator(); - assertEquals(it.next(), new Integer(2)); - assertEquals(it.next(), new Integer(3)); - assertFalse(it.hasNext()); - } - - /** - * toString contains toStrings of elements - */ - public void testDescendingToString() { - NavigableSet q = populatedSet(SIZE); - String s = q.toString(); - for (int i = 0; i < SIZE; ++i) { - assertTrue(s.contains(String.valueOf(i))); - } - } -// -// /** -// * A deserialized serialized set has same elements -// */ -// public void testDescendingSerialization() throws Exception { -// NavigableSet x = dset5(); -// NavigableSet y = serialClone(x); -// -// assertNotSame(y, x); -// assertEquals(x.size(), y.size()); -// assertEquals(x, y); -// assertEquals(y, x); -// while (!x.isEmpty()) { -// assertFalse(y.isEmpty()); -// assertEquals(x.pollFirst(), y.pollFirst()); -// } -// assertTrue(y.isEmpty()); -// } - - /** - * subSet returns set with keys in requested range - */ - public void testDescendingSubSetContents() { - NavigableSet set = dset5(); - SortedSet sm = set.subSet(m2, m4); - assertEquals(m2, sm.first()); - assertEquals(m3, sm.last()); - assertEquals(2, sm.size()); - assertFalse(sm.contains(m1)); - assertTrue(sm.contains(m2)); - assertTrue(sm.contains(m3)); - assertFalse(sm.contains(m4)); - assertFalse(sm.contains(m5)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(m2, k); - k = (Integer)(i.next()); - assertEquals(m3, k); - assertFalse(i.hasNext()); - Iterator j = sm.iterator(); - j.next(); - j.remove(); - assertFalse(set.contains(m2)); - assertEquals(4, set.size()); - assertEquals(1, sm.size()); - assertEquals(m3, sm.first()); - assertEquals(m3, sm.last()); - assertTrue(sm.remove(m3)); - assertTrue(sm.isEmpty()); - assertEquals(3, set.size()); - } - - public void testDescendingSubSetContents2() { - NavigableSet set = dset5(); - SortedSet sm = set.subSet(m2, m3); - assertEquals(1, sm.size()); - assertEquals(m2, sm.first()); - assertEquals(m2, sm.last()); - assertFalse(sm.contains(m1)); - assertTrue(sm.contains(m2)); - assertFalse(sm.contains(m3)); - assertFalse(sm.contains(m4)); - assertFalse(sm.contains(m5)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(m2, k); - assertFalse(i.hasNext()); - Iterator j = sm.iterator(); - j.next(); - j.remove(); - assertFalse(set.contains(m2)); - assertEquals(4, set.size()); - assertEquals(0, sm.size()); - assertTrue(sm.isEmpty()); - assertFalse(sm.remove(m3)); - assertEquals(4, set.size()); - } - - /** - * headSet returns set with keys in requested range - */ - public void testDescendingHeadSetContents() { - NavigableSet set = dset5(); - SortedSet sm = set.headSet(m4); - assertTrue(sm.contains(m1)); - assertTrue(sm.contains(m2)); - assertTrue(sm.contains(m3)); - assertFalse(sm.contains(m4)); - assertFalse(sm.contains(m5)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(m1, k); - k = (Integer)(i.next()); - assertEquals(m2, k); - k = (Integer)(i.next()); - assertEquals(m3, k); - assertFalse(i.hasNext()); - sm.clear(); - assertTrue(sm.isEmpty()); - assertEquals(2, set.size()); - assertEquals(m4, set.first()); - } - - /** - * tailSet returns set with keys in requested range - */ - public void testDescendingTailSetContents() { - NavigableSet set = dset5(); - SortedSet sm = set.tailSet(m2); - assertFalse(sm.contains(m1)); - assertTrue(sm.contains(m2)); - assertTrue(sm.contains(m3)); - assertTrue(sm.contains(m4)); - assertTrue(sm.contains(m5)); - Iterator i = sm.iterator(); - Object k; - k = (Integer)(i.next()); - assertEquals(m2, k); - k = (Integer)(i.next()); - assertEquals(m3, k); - k = (Integer)(i.next()); - assertEquals(m4, k); - k = (Integer)(i.next()); - assertEquals(m5, k); - assertFalse(i.hasNext()); - - SortedSet ssm = sm.tailSet(m4); - assertEquals(m4, ssm.first()); - assertEquals(m5, ssm.last()); - assertTrue(ssm.remove(m4)); - assertEquals(1, ssm.size()); - assertEquals(3, sm.size()); - assertEquals(4, set.size()); - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/BTreeSetTest.java b/src/test/java/org/mapdb/BTreeSetTest.java deleted file mode 100644 index f1632c009..000000000 --- a/src/test/java/org/mapdb/BTreeSetTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.mapdb; - - -import org.junit.Before; - -import java.util.Collections; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class BTreeSetTest extends HTreeSetTest{ - - @Before - public void setUp() throws Exception { - - hs = new BTreeMap(engine,BTreeMap.createRootRef(engine,BTreeKeySerializer.BASIC,null,0), - 6,false,0, BTreeKeySerializer.BASIC,null, - 0).keySet(); - - Collections.addAll(hs, objArray); - } -} diff --git a/src/test/java/org/mapdb/BindTest.java b/src/test/java/org/mapdb/BindTest.java deleted file mode 100644 index e4da51043..000000000 --- a/src/test/java/org/mapdb/BindTest.java +++ /dev/null @@ -1,217 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.util.Random; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicReference; - -import static org.junit.Assert.assertEquals; -import static org.mapdb.Fun.*; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class BindTest { - - BTreeMap m; - - @Before - public void init(){ - m = DBMaker.newMemoryDB().make().getTreeMap("test"); - } - - - @After - public void close(){ - m.engine.close(); - } - - - String[] split(String s){ - if(s==null) return null; - String[] ret = new String[s.length()]; - for(int i=0;i sec = new TreeSet(Fun.COMPARABLE_ARRAY_COMPARATOR); - - Bind.secondaryValues(m,sec,new Function2() { - @Override - public String[] run(Integer integer, String s) { - return split(s); - } - }); - - //filled if empty - assertEquals(5+3,sec.size()); - assert(sec.contains(new Object[]{2,"d"})); - assert(sec.contains(new Object[]{2,"v"})); - assert(sec.contains(new Object[]{2,"e"})); - - //old values preserved - m.put(2,"dvea"); - assertEquals(5+4,sec.size()); - assert(sec.contains(new Object[]{2,"d"})); - assert(sec.contains(new Object[]{2,"v"})); - assert(sec.contains(new Object[]{2,"e"})); - assert(sec.contains(new Object[]{2,"a"})); - - //old values deleted - m.put(2,"dva"); - assertEquals(5+3,sec.size()); - assert(sec.contains(new Object[]{2,"d"})); - assert(sec.contains(new Object[]{2,"v"})); - assert(sec.contains(new Object[]{2,"a"})); - - //all removed on delete - m.remove(2); - assertEquals(5,sec.size()); - - //all added on put - m.put(2,"dva"); - assertEquals(5+3,sec.size()); - assert(sec.contains(new Object[]{2,"d"})); - assert(sec.contains(new Object[]{2,"v"})); - assert(sec.contains(new Object[]{2,"a"})); - - } - - @Test public void secondary_keys(){ - m.put(1,"jedna"); - m.put(2,"dve"); - - Set sec = new TreeSet(Fun.COMPARABLE_ARRAY_COMPARATOR); - - Bind.secondaryKeys(m,sec,new Function2() { - @Override - public String[] run(Integer integer, String s) { - return split(s); - } - }); - - //filled if empty - assertEquals(5+3,sec.size()); - assert(sec.contains(new Object[]{"d",2})); - assert(sec.contains(new Object[]{"v",2})); - assert(sec.contains(new Object[]{"e",2})); - - //old values preserved - m.put(2,"dvea"); - assertEquals(5+4,sec.size()); - assert(sec.contains(new Object[]{"d",2})); - assert(sec.contains(new Object[]{"v",2})); - assert(sec.contains(new Object[]{"e",2})); - assert(sec.contains(new Object[]{"a",2})); - - //old values deleted - m.put(2,"dva"); - assertEquals(5+3,sec.size()); - assert(sec.contains(new Object[]{"d",2})); - assert(sec.contains(new Object[]{"v",2})); - assert(sec.contains(new Object[]{"a",2})); - - //all removed on delete - m.remove(2); - assertEquals(5,sec.size()); - - //all added on put - m.put(2,"dva"); - assertEquals(5+3,sec.size()); - assert(sec.contains(new Object[]{"d",2})); - assert(sec.contains(new Object[]{"v",2})); - assert(sec.contains(new Object[]{"a",2})); - - } - - @Test public void htreemap_listeners(){ - mapListeners(DBMaker.newMemoryDB().transactionDisable().make().getHashMap("test")); - } - - @Test public void btreemap_listeners(){ - mapListeners(DBMaker.newMemoryDB().transactionDisable().make().getTreeMap("test")); - } - - - void mapListeners(Bind.MapWithModificationListener test) { - final AtomicReference rkey = new AtomicReference(); - final AtomicReference roldVal = new AtomicReference(); - final AtomicReference rnewVal = new AtomicReference(); - - test.modificationListenerAdd(new Bind.MapListener() { - @Override - public void update(Object key, Object oldVal, Object newVal) { - rkey.set(key); - roldVal.set(oldVal); - rnewVal.set(newVal); - } - }); - - int max = (int) 1e6; - Random r = new Random(); - for(int i=0;i= 0) - if (((byte) read) == grep[p]) { - if (++p == grep.length) { - dataFile.seek(dataFile.getFilePointer() - grep.length); - dataFile.write("xxxxField".getBytes()); - break; - } - } else - p = 0; - dataFile.close(); - - try { - DBMaker.newFileDB(index).make(); - Assert.fail("Expected exception not thrown"); - } catch (final RuntimeException e) { - // will fail! - Assert.assertTrue("Wrong message", e.getMessage().contains("Could not set field value")); - } - - index.delete(); - data.delete(); - log.delete(); - - // assert that we can delete the db files - Assert.assertFalse("Can't delete index", index.exists()); - Assert.assertFalse("Can't delete data", data.exists()); - Assert.assertFalse("Can't delete log", log.exists()); - } -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/CCTest.java b/src/test/java/org/mapdb/CCTest.java deleted file mode 100644 index b54f66f35..000000000 --- a/src/test/java/org/mapdb/CCTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.mapdb; - -import org.junit.Assert; -import org.junit.Test; - -public class CCTest { - - @Test public void concurency(){ - long i = 2; - while(i m = db.getHashMap("name"); - for(Integer i = 0;i<1000;i++){ - m.put(i,i); - } - Caches.WeakSoftRef engine = (Caches.WeakSoftRef)db.engine; - assertTrue(engine.items.size()!=0); - - for(Integer i = 0;i<1000;i++){ - Integer a = m.remove(i); - assertEquals(i, a); - } - db.close(); - int counter = 10000; - while(engine.cleanerFinished.getCount()!=0 && counter>0){ - Thread.sleep(1); - counter--; - } - assertEquals(0,engine.cleanerFinished.getCount()); - } -} diff --git a/src/test/java/org/mapdb/ClosedThrowsExceptionTest.java b/src/test/java/org/mapdb/ClosedThrowsExceptionTest.java deleted file mode 100644 index 34cb41282..000000000 --- a/src/test/java/org/mapdb/ClosedThrowsExceptionTest.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.util.Map; - -import static org.junit.Assert.assertEquals; - -/** - * check that `IllegalAccessError` is thrown after DB was closed - */ -public abstract class ClosedThrowsExceptionTest { - - abstract DB db(); - - DB db; - - - @Before public void init(){ - db = db(); - } - - @After public void close(){ - db = null; - } - - static public class Def extends ClosedThrowsExceptionTest{ - @Override DB db() { - return DBMaker.newMemoryDB().make(); - } - } - - static public class Async extends ClosedThrowsExceptionTest{ - @Override DB db() { - return DBMaker.newMemoryDB().asyncWriteEnable().make(); - } - } - - static public class NoCache extends ClosedThrowsExceptionTest{ - @Override DB db() { - return DBMaker.newMemoryDB().cacheDisable().make(); - } - } - - static public class HardRefCache extends ClosedThrowsExceptionTest{ - @Override DB db() { - return DBMaker.newMemoryDB().cacheHardRefEnable().make(); - } - } - - static public class TX extends ClosedThrowsExceptionTest{ - @Override DB db() { - return DBMaker.newMemoryDB().makeTxMaker().makeTx(); - } - } - - static public class storeHeap extends ClosedThrowsExceptionTest{ - @Override DB db() { - return new DB(new StoreHeap()); - } - } - - @Test(expected = IllegalAccessError.class) - public void closed_getHashMap(){ - db.getHashMap("test"); - db.close(); - db.getHashMap("test"); - } - - @Test() - public void closed_getNamed(){ - db.getHashMap("test"); - db.close(); - assertEquals(null, db.getNameForObject("test")); - } - - - @Test(expected = IllegalAccessError.class) - public void closed_put(){ - Map m = db.getHashMap("test"); - db.close(); - m.put("aa","bb"); - } - - - @Test(expected = IllegalAccessError.class) - public void closed_remove(){ - Map m = db.getHashMap("test"); - m.put("aa","bb"); - db.close(); - m.remove("aa"); - } - - @Test(expected = IllegalAccessError.class) - public void closed_close(){ - Map m = db.getHashMap("test"); - m.put("aa","bb"); - db.close(); - db.close(); - } - - @Test(expected = IllegalAccessError.class) - public void closed_rollback(){ - Map m = db.getHashMap("test"); - m.put("aa","bb"); - db.close(); - db.rollback(); - } - - @Test(expected = IllegalAccessError.class) - public void closed_commit(){ - Map m = db.getHashMap("test"); - m.put("aa","bb"); - db.close(); - db.commit(); - } - - @Test - public void closed_is_closed(){ - Map m = db.getHashMap("test"); - m.put("aa","bb"); - db.close(); - assertEquals(true,db.isClosed()); - } - - @Test(expected = IllegalAccessError.class) - public void closed_engine_get(){ - long recid = db.getEngine().put("aa",Serializer.STRING); - db.close(); - db.getEngine().get(recid,Serializer.STRING); - } - - @Test(expected = IllegalAccessError.class) - public void closed_engine_put(){ - db.close(); - long recid = db.getEngine().put("aa",Serializer.STRING); - } - - @Test(expected = IllegalAccessError.class) - public void closed_engine_update(){ - long recid = db.getEngine().put("aa",Serializer.STRING); - db.close(); - db.getEngine().update(recid, "aax", Serializer.STRING); - } - - @Test(expected = IllegalAccessError.class) - public void closed_engine_delete(){ - long recid = db.getEngine().put("aa",Serializer.STRING); - db.close(); - db.getEngine().delete(recid, Serializer.STRING); - } - -} diff --git a/src/test/java/org/mapdb/CompressTest.java b/src/test/java/org/mapdb/CompressTest.java deleted file mode 100644 index 900f3ebd9..000000000 --- a/src/test/java/org/mapdb/CompressTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; - -import static org.junit.Assert.*; - -public class CompressTest{ - - DB db; - - @Before public void init(){ - db = DBMaker - .newMemoryDB() - .cacheDisable() - .compressionEnable() - .make(); - } - - - @After - public void close(){ - db.close(); - } - - @Test - public void check_instance() throws Exception { - Store s = Store.forDB(db); - assertTrue(s.compress); - } - - - @Test - public void put_get_update() throws Exception { - long recid = db.engine.put("aaaa", Serializer.STRING_NOSIZE); - assertEquals("aaaa",db.engine.get(recid, Serializer.STRING_NOSIZE)); - db.engine.update(recid, "bbbb", Serializer.STRING_NOSIZE); - assertEquals("bbbb",db.engine.get(recid, Serializer.STRING_NOSIZE)); - db.engine.delete(recid,Serializer.STRING_NOSIZE); - assertEquals(null,db.engine.get(recid, Serializer.STRING_NOSIZE)); - - } - - - @Test - public void short_compression() throws Exception { - byte[] b = new byte[]{1,2,3,4,5,33,3}; - byte[] b2 = UtilsTest.clone(b, new Serializer.CompressionWrapper(Serializer.BYTE_ARRAY)); - assertArrayEquals(b,b2); - } - - @Test public void large_compression() throws IOException { - byte[] b = new byte[1024]; - b[0] = 1; - b[4] = 5; - b[1000] = 1; - - Serializer ser = new Serializer.CompressionWrapper(Serializer.BYTE_ARRAY); - assertArrayEquals(b, UtilsTest.clone(b, ser)); - - //check compressed size is actually smaller - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - ser.serialize(out,b); - assertTrue(out.pos<100); - } - - -} diff --git a/src/test/java/org/mapdb/DBCollectionTest.kt b/src/test/java/org/mapdb/DBCollectionTest.kt new file mode 100644 index 000000000..ddeedbe56 --- /dev/null +++ b/src/test/java/org/mapdb/DBCollectionTest.kt @@ -0,0 +1,185 @@ +package org.mapdb + +import io.kotlintest.should +import io.kotlintest.shouldBe +import org.junit.Assert.assertTrue +import org.mapdb.cli.Export +import org.mapdb.cli.Import +import org.mapdb.db.DB +import org.mapdb.io.DataInput2 +import org.mapdb.io.DataInput2ByteArray +import org.mapdb.io.DataOutput2ByteArray +import org.mapdb.ser.Serializer +import org.mapdb.ser.Serializers +import org.mapdb.util.Exporter + +class DBCollectionTest: DBWordSpec({ + + for(a in adapters()){ + a.name should { + "wrong serializer fail on reopen"{ + TT.withTempFile { f-> + var db = DB.Maker.appendFile(f).make() + a.open(db, "name", Serializers.INTEGER) + db.close() + + db = DB.Maker.appendFile(f).make() + TT.assertFailsWith(DBException.WrongSerializer::class) { + a.open(db, "name", Serializers.LONG) + } + } + } + + "use the same instance"{ + val db = DB.Maker.heapSer().make() + val c1 = a.open(db, "name", Serializers.INTEGER) + val c2 = a.open(db, "name", Serializers.INTEGER) + val c3 = a.open(db, "name", Serializers.INTEGER) + + assertTrue(c1===c2 && c2===c3) + } + + "import fails on existing"{ + TT.withTempFile { f -> + var db = DB.Maker.appendFile(f).make() + a.open(db, "name", Serializers.INTEGER) + db.close() + + db = DB.Maker.appendFile(f).make() + val input = DataInput2ByteArray(ByteArray(0)) + TT.assertFailsWith(DBException.WrongConfig::class){ + a.import(db, "name", Serializers.INTEGER, input ) + } + } + } + + "export"{ + val db1 = DB.Maker.heapSer().make() + val c1 = a.open(db1, "aa", Serializers.INTEGER) + + for(i in 1..100) + a.add(c1, i) + + val output = DataOutput2ByteArray() + (c1 as Exporter).exportToDataOutput2(output) + + val input = DataInput2ByteArray(output.copyBytes()) + + val db2 = DB.Maker.heapSer().make() + val c2 = a.import(db2, "aa", Serializers.INTEGER, input) + + val all = a.getAll(c2).toList() + for(i in 1..100){ + all[i-1] shouldBe i + } + } + + "cli export"{ + TT.withTempFile { dbf -> + var db = DB.Maker.appendFile(dbf).make() + var c = a.open(db, "name", Serializers.INTEGER) + for(i in 1..100) + a.add(c, i) + db.close() + + val outf = TT.tempNotExistFile() + //export from cli + Export.main(arrayOf("-d",dbf.path, "-o", outf.path, "-n","name")) + + outf.length() should {it>0L} + + db = DB.Maker.heapSer().make() + val input = DataInput2ByteArray(outf.readBytes()) + c = a.import(db, "name2", Serializers.INTEGER, input ) + + val all = a.getAll(c).toList() + for(i in 1..100){ + all[i-1] shouldBe i + } + } + } + + + "cli import"{ + TT.withTempFile { dbf -> + var db = DB.Maker.heapSer().make() + var c = a.open(db, "name", Serializers.INTEGER) + for(i in 1..100) + a.add(c, i) + + val output = DataOutput2ByteArray() + (c as Exporter).exportToDataOutput2(output) + + val outf = TT.tempFile() + outf.writeBytes(output.copyBytes()) + + //import from cli + Import.main(arrayOf("-d",dbf.path, "-i", outf.path, "-n","name")) + + dbf.length() should {it>0L} + + db = DB.Maker.appendFile(dbf).make() + c = a.open(db, "name", Serializers.INTEGER) + + val all = a.getAll(c).toList() + for(i in 1..100){ + all[i-1] shouldBe i + } + } + } + + } + } + +}){ + + companion object { + + abstract class Adapter{ + abstract fun open(db: DB, name:String, serializer: Serializer<*>):C + + abstract fun import(db: DB, name:String, serializer: Serializer<*>, input: DataInput2):C + + abstract fun add(c:C, e:Any?) + + abstract fun getAll(c:C):Iterable + + abstract val name:String + } + + + fun adapters():List>{ +/* + + val qAdapter = object: Adapter>() { + + override fun import(db: DB, name: String, serializer: Serializer<*>, input: DataInput2): LinkedFIFOQueue { + return db.queue(name, serializer) + .importFromDataInput2(input) + .make() as LinkedFIFOQueue + } + + + override fun open(db: DB, name: String, serializer: Serializer<*>): LinkedFIFOQueue { + return db.queue(name, serializer).make() as LinkedFIFOQueue + } + + override fun add(c: LinkedFIFOQueue, e: Any?) { + c.add(e) + } + + override fun getAll(c: LinkedFIFOQueue): Iterable { + return c + } + + override val name = "queue" + + } +*/ + + return emptyList() + + } + } +} + diff --git a/src/test/java/org/mapdb/DBMakerTest.java b/src/test/java/org/mapdb/DBMakerTest.java deleted file mode 100644 index 2d860ad4b..000000000 --- a/src/test/java/org/mapdb/DBMakerTest.java +++ /dev/null @@ -1,417 +0,0 @@ -package org.mapdb; - -import org.junit.Test; -import org.mapdb.EngineWrapper.ReadOnlyEngine; - -import java.io.File; -import java.io.IOError; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.*; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ConcurrentNavigableMap; - -import static org.junit.Assert.*; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class DBMakerTest{ - - - private void verifyDB(DB db) { - Map m = db.getHashMap("test"); - m.put(1,2); - assertEquals(2,m.get(1)); - } - - - @Test - public void testNewMemoryDB() throws Exception { - DB db = DBMaker - .newMemoryDB() - .transactionDisable() - .make(); - verifyDB(db); - } - - - @Test - public void testNewFileDB() throws Exception { - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f) - .transactionDisable().make(); - verifyDB(db); - } - - @Test - public void testDisableTransactions() throws Exception { - DBMaker.newMemoryDB().make(); - } - - @Test - public void testDisableCache() throws Exception { - DB db = DBMaker - .newMemoryDB() - .transactionDisable() - .cacheDisable() - .make(); - verifyDB(db); - Store s = Store.forDB(db); - assertEquals(s.getClass(), StoreDirect.class); - } - - @Test - public void testAsyncWriteEnable() throws Exception { - DB db = DBMaker - .newMemoryDB() - .asyncWriteEnable() - .make(); - verifyDB(db); - assertEquals(db.engine.getClass(), Caches.HashTable.class); - EngineWrapper w = (EngineWrapper) db.engine; - assertEquals(w.getWrappedEngine().getClass(),AsyncWriteEngine.class); - } - - @Test - public void testMake() throws Exception { - DB db = DBMaker - .newFileDB(UtilsTest.tempDbFile()) - .transactionDisable() - .make(); - verifyDB(db); - //check default values are set - EngineWrapper w = (EngineWrapper) db.engine; - assertTrue(w instanceof Caches.HashTable); - assertEquals(1024 * 32, ((Caches.HashTable) w).cacheMaxSize); - StoreDirect s = (StoreDirect) w.getWrappedEngine(); - assertTrue(s.index instanceof Volume.FileChannelVol); - assertTrue(s.phys instanceof Volume.FileChannelVol); - } - - @Test - public void testMakeMapped() throws Exception { - DB db = DBMaker - .newFileDB(UtilsTest.tempDbFile()) - .transactionDisable() - .mmapFileEnable() - .make(); - verifyDB(db); - //check default values are set - EngineWrapper w = (EngineWrapper) db.engine; - assertTrue(w instanceof Caches.HashTable); - assertEquals(1024 * 32, ((Caches.HashTable) w).cacheMaxSize); - StoreDirect s = (StoreDirect) w.getWrappedEngine(); - assertTrue(s.index instanceof Volume.MappedFileVol); - assertTrue(s.phys instanceof Volume.MappedFileVol); - } - - @Test - public void testCacheHardRefEnable() throws Exception { - DB db = DBMaker - .newMemoryDB() - .transactionDisable() - .cacheHardRefEnable() - .make(); - verifyDB(db); - assertTrue(db.engine.getClass() == Caches.HardRef.class); - } - - @Test - public void testCacheWeakRefEnable() throws Exception { - DB db = DBMaker - .newMemoryDB() - .transactionDisable() - .cacheWeakRefEnable() - .make(); - verifyDB(db); - assertTrue(db.engine.getClass() == Caches.WeakSoftRef.class); - assertTrue(((Caches.WeakSoftRef)db.engine).useWeakRef); - } - - - @Test - public void testCacheSoftRefEnable() throws Exception { - DB db = DBMaker - .newMemoryDB() - .transactionDisable() - .cacheSoftRefEnable() - .make(); - verifyDB(db); - assertTrue(db.engine.getClass() == Caches.WeakSoftRef.class); - assertFalse(((Caches.WeakSoftRef)db.engine).useWeakRef); - } - - @Test - public void testCacheLRUEnable() throws Exception { - DB db = DBMaker - .newMemoryDB() - .transactionDisable() - .cacheLRUEnable() - .make(); - verifyDB(db); - assertTrue(db.engine.getClass() == Caches.LRU.class); - db.close(); - } - - @Test - public void testCacheSize() throws Exception { - DB db = DBMaker - .newMemoryDB() - .transactionDisable() - .cacheSize(1000) - .make(); - verifyDB(db); - assertEquals(1024, ((Caches.HashTable) db.engine).cacheMaxSize); - } - - @Test public void read_only() throws IOException { - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).make(); - db.close(); - db = DBMaker - .newFileDB(f) - .deleteFilesAfterClose() - .readOnly() - .make(); - assertTrue(db.engine instanceof ReadOnlyEngine); - db.close(); - } - - @Test(expected = IllegalArgumentException.class) - public void reopen_wrong_checksum() throws IOException { - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).make(); - db.close(); - db = DBMaker - .newFileDB(f) - .deleteFilesAfterClose() - .cacheDisable() - - .checksumEnable() - .make(); - EngineWrapper w = (EngineWrapper) db.engine; - assertTrue(w instanceof TxEngine); - - Store s = Store.forEngine(w); - assertTrue(s.checksum); - assertTrue(!s.compress); - assertTrue(s.password==null); - db.close(); - } - - - @Test public void checksum() throws IOException { - File f = UtilsTest.tempDbFile(); - DB db = DBMaker - .newFileDB(f) - .deleteFilesAfterClose() - .cacheDisable() - - .checksumEnable() - .make(); - - Store s = Store.forDB(db); - assertTrue(s.checksum); - assertTrue(!s.compress); - assertTrue(s.password==null); - db.close(); - } - - @Test public void encrypt() throws IOException { - File f = UtilsTest.tempDbFile(); - DB db = DBMaker - .newFileDB(f) - .deleteFilesAfterClose() - .cacheDisable() - - .encryptionEnable("adqdqwd") - .make(); - Store s = Store.forDB(db); - assertTrue(!s.checksum); - assertTrue(!s.compress); - assertTrue(s.password!=null); - db.close(); - } - - - @Test(expected = IllegalArgumentException.class) - public void reopen_wrong_encrypt() throws IOException { - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).make(); - db.close(); - db = DBMaker - .newFileDB(f) - .deleteFilesAfterClose() - .cacheDisable() - - .encryptionEnable("adqdqwd") - .make(); - Store s = Store.forDB(db); - assertTrue(!s.checksum); - assertTrue(!s.compress); - assertTrue(s.password!=null); - db.close(); - } - - - @Test public void compress() throws IOException { - File f = UtilsTest.tempDbFile(); - DB db = DBMaker - .newFileDB(f) - .deleteFilesAfterClose() - .cacheDisable() - .compressionEnable() - .make(); - Store s = Store.forDB(db); - assertTrue(!s.checksum); - assertTrue(s.compress); - assertTrue(s.password==null); - db.close(); - } - - @Test(expected = IllegalArgumentException.class) - public void reopen_wrong_compress() throws IOException { - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).make(); - db.close(); - db = DBMaker - .newFileDB(f) - .deleteFilesAfterClose() - .cacheDisable() - - .compressionEnable() - .make(); - EngineWrapper w = (EngineWrapper) db.engine; - assertTrue(w instanceof TxEngine); - Store s = Store.forEngine(w); - assertTrue(!s.checksum); - assertTrue(s.compress); - assertTrue(s.password==null); - - db.close(); - } - - - - @Test public void close_on_jvm_shutdown(){ - DBMaker - .newTempFileDB() - .closeOnJvmShutdown() - .deleteFilesAfterClose() - .make(); - } - - @Test public void tempTreeMap(){ - ConcurrentNavigableMap m = DBMaker.newTempTreeMap(); - m.put(111L,"wfjie"); - assertTrue(m.getClass().getName().contains("BTreeMap")); - } - - @Test public void tempHashMap(){ - ConcurrentMap m = DBMaker.newTempHashMap(); - m.put(111L,"wfjie"); - assertTrue(m.getClass().getName().contains("HTreeMap")); - } - - @Test public void tempHashSet(){ - Set m = DBMaker.newTempHashSet(); - m.add(111L); - assertTrue(m.getClass().getName().contains("HTreeMap")); - } - - @Test public void tempTreeSet(){ - NavigableSet m = DBMaker.newTempTreeSet(); - m.add(111L); - assertTrue(m.getClass().getName().contains("BTreeMap")); - } - - @Test public void rafEnableKeepIndexMapped(){ - DB db = DBMaker.newFileDB(UtilsTest.tempDbFile()) - .mmapFileEnablePartial() - .make(); - Engine e = db.getEngine(); - while(e instanceof EngineWrapper) - e = ((EngineWrapper)e).getWrappedEngine(); - StoreDirect d = (StoreDirect) e; - assertTrue(d.index instanceof Volume.MappedFileVol); - assertTrue(d.phys instanceof Volume.FileChannelVol); - } - - @Test(expected = UnsupportedOperationException.class) - public void limitDisabledAppend(){ - DBMaker.newAppendFileDB(UtilsTest.tempDbFile()).sizeLimit(1).make(); - } - - @Test() - public void sizeLimit(){ - long g = 1024*1024*1024; - assertEquals(g/2,DBMaker.newMemoryDB().sizeLimit(0.5).propsGetLong(DBMaker.Keys.sizeLimit,0)); - assertEquals(g,DBMaker.newMemoryDB().sizeLimit(1).propsGetLong(DBMaker.Keys.sizeLimit,0)); - } - - - @Test public void keys_value_matches() throws IllegalAccessException { - Class c = DBMaker.Keys.class; - Set s = new TreeSet(); - for (Field f : c.getDeclaredFields()) { - f.setAccessible(true); - String value = (String) f.get(null); - - String expected = f.getName().replaceFirst("^[^_]+_",""); - assertEquals(expected, value); - } - } - - File folderDoesNotExist = new File("folder-does-not-exit/db.aaa"); - - @Test(expected = IOError.class) - public void nonExistingFolder(){ - DBMaker.newFileDB(folderDoesNotExist).make(); - } - - public void nonExistingFolder3(){ - DBMaker.newFileDB(folderDoesNotExist).mmapFileEnable().make(); - } - - - @Test(expected = IOError.class) - public void nonExistingFolder2(){ - DBMaker - .newFileDB(folderDoesNotExist) - .snapshotEnable() - .commitFileSyncDisable() - .makeTxMaker(); - } - - @Test public void treeset_pump_presert(){ - List unsorted = Arrays.asList(4,7,5,12,9,10,11,0); - - NavigableSet s = DBMaker.newMemoryDB().cacheDisable().transactionDisable().make() - .createTreeSet("t") - .pumpPresort(10) - .pumpSource(unsorted.iterator()) - .make(); - - assertEquals(Integer.valueOf(0),s.first()); - assertEquals(Integer.valueOf(12),s.last()); - } - - @Test public void treemap_pump_presert(){ - List unsorted = Arrays.asList(4,7,5,12,9,10,11,0); - - NavigableMap s = DBMaker.newMemoryDB().cacheDisable().transactionDisable().make() - .createTreeMap("t") - .pumpPresort(10) - .pumpSource(unsorted.iterator(), Fun.extractNoTransform()) - .make(); - - assertEquals(Integer.valueOf(0),s.firstEntry().getKey()); - assertEquals(Integer.valueOf(12),s.lastEntry().getKey()); - } - - @Test public void heap_store(){ - DB db = DBMaker.newHeapDB().make(); - Engine s = Store.forDB(db); - - assertTrue(s instanceof StoreHeap); - } -} diff --git a/src/test/java/org/mapdb/DBTest.java b/src/test/java/org/mapdb/DBTest.java deleted file mode 100644 index 4aa9d2ef7..000000000 --- a/src/test/java/org/mapdb/DBTest.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.util.Map; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - - - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class DBTest { - - Engine engine; - DB db; - - - @Before public void init(){ - engine = new StoreDirect(null); - db = new DB(engine); - } - - - @After - public void close(){ - db = null; - } - - @Test - public void testGetHashMap() throws Exception { - Map m1 = db.getHashMap("test"); - m1.put(1,2); - m1.put(3,4); - assertTrue(m1 == db.getHashMap("test")); - assertEquals(m1, new DB(engine).getHashMap("test")); - } - - - - @Test - public void testGetHashSet() throws Exception { - Set m1 = db.getHashSet("test"); - m1.add(1); - m1.add(2); - assertTrue(m1 == db.getHashSet("test")); - assertEquals(m1, new DB(engine).getHashSet("test")); - } - - @Test - public void testGetTreeMap() throws Exception { - Map m1 = db.getTreeMap("test"); - m1.put(1,2); - m1.put(3,4); - assertTrue(m1 == db.getTreeMap("test")); - assertEquals(m1, new DB(engine).getTreeMap("test")); - } - - @Test - public void testGetTreeSet() throws Exception { - Set m1 = db.getTreeSet("test"); - m1.add(1); - m1.add(2); - assertTrue(m1 == db.getTreeSet("test")); - assertEquals(m1, new DB(engine).getTreeSet("test")); - } - - @Test(expected = IllegalAccessError.class) - public void testClose() throws Exception { - db.close(); - db.getHashMap("test"); - } - - - @Test public void getAll(){ - db.createAtomicString("aa","100"); - db.getHashMap("zz").put(11,"12"); - Map all = db.getAll(); - - assertEquals(2,all.size()); - assertEquals("100",((Atomic.String)all.get("aa")).get()); - assertEquals("12",((HTreeMap)all.get("zz")).get(11)); - - } - - @Test public void rename(){ - db.getHashMap("zz").put(11,"12"); - db.rename("zz","aa"); - assertEquals("12",db.getHashMap("aa").get(11)); - } - - - @Test(expected = IllegalArgumentException.class) - public void testCollectionExists(){ - db.getHashMap("test"); - db.checkNameNotExists("test"); - } - - @Test(expected = IllegalArgumentException.class) - public void testQueueExists(){ - db.getQueue("test"); - db.checkNameNotExists("test"); - } - - @Test(expected = IllegalArgumentException.class) - public void testAtomicExists(){ - db.getAtomicInteger("test"); - db.checkNameNotExists("test"); - } - - @Test - public void test_issue_315() { - DB db = DBMaker.newMemoryDB().cacheDisable().make(); - - final String item1 = "ITEM_ONE"; - final String item2 = "ITEM_ONE_TWO"; - final String item3 = "ITEM_ONETWO"; - final String item4 = "ITEM_ONE__TWO"; - final String item5 = "ITEM_ONE.TWO"; - final String item6 = "ITEM_ONE.__.TWO"; - - - db.createTreeMap(item1).make(); - db.createTreeSet(item2).make(); - db.createTreeSet(item3).make(); - db.createTreeSet(item4).make(); - db.createTreeSet(item5).make(); - db.createTreeSet(item6).make(); - - - db.delete(item1); - - assertTrue(db.get(item1) == null); - assertTrue(db.get(item2) instanceof Set); - assertTrue(db.get(item3) instanceof Set); - assertTrue(db.get(item4) instanceof Set); - assertTrue(db.get(item5) instanceof Set); - assertTrue(db.get(item6) instanceof Set); - - } - -} diff --git a/src/test/java/org/mapdb/DataOutput2Test.java b/src/test/java/org/mapdb/DataOutput2Test.java deleted file mode 100644 index 4950c9620..000000000 --- a/src/test/java/org/mapdb/DataOutput2Test.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - - -public class DataOutput2Test { - - //TODO more tests here for compability between DataIO.ByteArrayDataOutput and other DataInputs - - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - - DataIO.DataInputByteArray in(){ - return new DataIO.DataInputByteArray(out.buf); - } - - @Test - public void testWriteFloat() throws Exception { - float f = 12.1239012093e-19F; - out.writeFloat(f); - DataIO.DataInputByteArray in = in(); - assertEquals(Float.floatToIntBits(f),Float.floatToIntBits(in.readFloat())); - assertEquals(4,in.pos); - } - - @Test - public void testWriteDouble() throws Exception { - double f = 12.123933423523012093e-199; - out.writeDouble(f); - DataIO.DataInputByteArray in = in(); - assertEquals(Double.doubleToLongBits(f),Double.doubleToLongBits(in.readDouble())); - assertEquals(8,in.pos); - } -} diff --git a/src/test/java/org/mapdb/EngineTest.java b/src/test/java/org/mapdb/EngineTest.java deleted file mode 100644 index 0d6fd7bd3..000000000 --- a/src/test/java/org/mapdb/EngineTest.java +++ /dev/null @@ -1,250 +0,0 @@ -package org.mapdb; - - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.mapdb.Serializer.BYTE_ARRAY_NOSIZE; - -/** - * Tests contract of various implementations of Engine interface - */ -public abstract class EngineTest{ - - protected abstract ENGINE openEngine(); - - void reopen(){ - if(!canReopen()) return; - e.close(); - e=openEngine(); - } - - boolean canReopen(){return true;} - boolean canRollback(){return true;} - - ENGINE e; - @Before public void init(){ - e = openEngine(); - } - - @Test public void put_get(){ - Long l = 11231203099090L; - long recid = e.put(l, Serializer.LONG); - assertEquals(l, e.get(recid, Serializer.LONG)); - } - - @Test public void put_reopen_get(){ - if(!canReopen()) return; - Long l = 11231203099090L; - long recid = e.put(l, Serializer.LONG); - e.commit(); - reopen(); - assertEquals(l, e.get(recid, Serializer.LONG)); - } - - @Test public void put_get_large(){ - byte[] b = new byte[(int) 1e6]; - new Random().nextBytes(b); - long recid = e.put(b, Serializer.BYTE_ARRAY_NOSIZE); - assertArrayEquals(b, e.get(recid, Serializer.BYTE_ARRAY_NOSIZE)); - } - - @Test public void put_reopen_get_large(){ - if(!canReopen()) return; - byte[] b = new byte[(int) 1e6]; - new Random().nextBytes(b); - long recid = e.put(b, Serializer.BYTE_ARRAY_NOSIZE); - e.commit(); - reopen(); - assertArrayEquals(b, e.get(recid, Serializer.BYTE_ARRAY_NOSIZE)); - } - - - @Test public void first_recid(){ - assertEquals(Store.LAST_RESERVED_RECID+1, e.put(1,Serializer.INTEGER)); - } - - - @Test public void compact0(){ - Long v1 = 129031920390121423L; - Long v2 = 909090901290129990L; - Long v3 = 998898989L; - long recid1 = e.put(v1, Serializer.LONG); - long recid2 = e.put(v2, Serializer.LONG); - - e.commit(); - e.compact(); - - assertEquals(v1, e.get(recid1,Serializer.LONG)); - assertEquals(v2, e.get(recid2,Serializer.LONG)); - long recid3 = e.put(v3, Serializer.LONG); - assertEquals(v1, e.get(recid1,Serializer.LONG)); - assertEquals(v2, e.get(recid2,Serializer.LONG)); - assertEquals(v3, e.get(recid3,Serializer.LONG)); - e.commit(); - assertEquals(v1, e.get(recid1,Serializer.LONG)); - assertEquals(v2, e.get(recid2,Serializer.LONG)); - assertEquals(v3, e.get(recid3,Serializer.LONG)); - - } - - - @Test public void compact(){ - Map recids = new HashMap(); - for(Long l=0L;l<1000;l++){ - recids.put(l, - e.put(l, Serializer.LONG)); - } - - e.commit(); - e.compact(); - - for(Map.Entry m:recids.entrySet()){ - Long recid= m.getValue(); - Long value = m.getKey(); - assertEquals(value, e.get(recid, Serializer.LONG)); - } - - - } - - - @Test public void compact2(){ - Map recids = new HashMap(); - for(Long l=0L;l<1000;l++){ - recids.put(l, - e.put(l, Serializer.LONG)); - } - - e.commit(); - e.compact(); - for(Long l=1000L;l<2000;l++){ - recids.put(l, e.put(l, Serializer.LONG)); - } - - for(Map.Entry m:recids.entrySet()){ - Long recid= m.getValue(); - Long value = m.getKey(); - assertEquals(value, e.get(recid, Serializer.LONG)); - } - } - - - @Test public void compact_large_record(){ - byte[] b = new byte[100000]; - long recid = e.put(b, Serializer.BYTE_ARRAY_NOSIZE); - e.commit(); - e.compact(); - assertArrayEquals(b, e.get(recid, Serializer.BYTE_ARRAY_NOSIZE)); - } - - - @Test public void testSetGet(){ - long recid = e.put((long) 10000, Serializer.LONG); - Long s2 = e.get(recid, Serializer.LONG); - assertEquals(s2, Long.valueOf(10000)); - } - - - - @Test - public void large_record(){ - byte[] b = new byte[100000]; - Arrays.fill(b, (byte) 111); - long recid = e.put(b, BYTE_ARRAY_NOSIZE); - byte[] b2 = e.get(recid, BYTE_ARRAY_NOSIZE); - assertArrayEquals(b,b2); - } - - @Test public void large_record_update(){ - byte[] b = new byte[100000]; - Arrays.fill(b, (byte) 111); - long recid = e.put(b, BYTE_ARRAY_NOSIZE); - Arrays.fill(b, (byte)222); - e.update(recid, b, BYTE_ARRAY_NOSIZE); - byte[] b2 = e.get(recid, BYTE_ARRAY_NOSIZE); - assertArrayEquals(b,b2); - e.commit(); - reopen(); - b2 = e.get(recid, BYTE_ARRAY_NOSIZE); - assertArrayEquals(b,b2); - } - - @Test public void large_record_delete(){ - byte[] b = new byte[100000]; - Arrays.fill(b, (byte) 111); - long recid = e.put(b, BYTE_ARRAY_NOSIZE); - e.delete(recid, BYTE_ARRAY_NOSIZE); - } - - - @Test public void large_record_larger(){ - byte[] b = new byte[10000000]; - Arrays.fill(b, (byte) 111); - long recid = e.put(b, BYTE_ARRAY_NOSIZE); - byte[] b2 = e.get(recid, BYTE_ARRAY_NOSIZE); - assertArrayEquals(b,b2); - e.commit(); - reopen(); - b2 = e.get(recid, BYTE_ARRAY_NOSIZE); - assertArrayEquals(b,b2); - - } - - - @Test public void test_store_reopen(){ - long recid = e.put("aaa", Serializer.STRING_NOSIZE); - e.commit(); - reopen(); - - String aaa = e.get(recid, Serializer.STRING_NOSIZE); - assertEquals("aaa",aaa); - } - - @Test public void test_store_reopen_nocommit(){ - long recid = e.put("aaa", Serializer.STRING_NOSIZE); - e.commit(); - e.update(recid,"bbb",Serializer.STRING_NOSIZE); - reopen(); - - String expected = canRollback()&&canReopen()?"aaa":"bbb"; - assertEquals(expected, e.get(recid, Serializer.STRING_NOSIZE)); - } - - - @Test public void rollback(){ - long recid = e.put("aaa", Serializer.STRING_NOSIZE); - e.commit(); - e.update(recid, "bbb", Serializer.STRING_NOSIZE); - - if(!canRollback())return; - e.rollback(); - - assertEquals("aaa",e.get(recid, Serializer.STRING_NOSIZE)); - - } - - @Test public void rollback_reopen(){ - long recid = e.put("aaa", Serializer.STRING_NOSIZE); - e.commit(); - e.update(recid, "bbb", Serializer.STRING_NOSIZE); - - if(!canRollback())return; - e.rollback(); - - assertEquals("aaa",e.get(recid, Serializer.STRING_NOSIZE)); - reopen(); - assertEquals("aaa",e.get(recid, Serializer.STRING_NOSIZE)); - - } - - - -} diff --git a/src/test/java/org/mapdb/EngineWrapper_ImmutabilityCheckEngine.java b/src/test/java/org/mapdb/EngineWrapper_ImmutabilityCheckEngine.java deleted file mode 100644 index 614186262..000000000 --- a/src/test/java/org/mapdb/EngineWrapper_ImmutabilityCheckEngine.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class EngineWrapper_ImmutabilityCheckEngine { - - @Test - public void test(){ - Engine e = new StoreDirect(null); - e = new EngineWrapper.ImmutabilityCheckEngine(e); - - List rec = new ArrayList(); - rec.add("aa"); - long recid = e.put(rec,Serializer.BASIC); - rec.add("bb"); - - try{ - e.update(recid, rec, Serializer.BASIC); - fail("should throw exception"); - }catch(AssertionError ee){ - assertTrue(ee.getMessage().startsWith("Record instance was modified")); - } - - try{ - e.close(); - fail("should throw exception"); - }catch(AssertionError ee){ - assertTrue(ee.getMessage().startsWith("Record instance was modified")); - } - } - -} diff --git a/src/test/java/org/mapdb/ExamplesTest.java b/src/test/java/org/mapdb/ExamplesTest.java deleted file mode 100644 index a3b4f1bdc..000000000 --- a/src/test/java/org/mapdb/ExamplesTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.mapdb; - - -import examples.*; -import org.junit.Test; - -import java.io.IOException; - -public class ExamplesTest { - - static final String[] args= new String[0]; - - @Test public void _HelloWorld() throws IOException { - _HelloWorld.main(args); - } - - @Test public void _TempMap(){ - _TempMap.main(args); - } - - @Test public void Cache(){ - CacheEntryExpiry.main(args); - } - - @Test public void Compression(){ - Compression.main(args); - } - - @Test public void Huge_Insert() throws IOException { - Huge_Insert.main(args); - } - - - - @Test public void Custom_Value() throws IOException { - Custom_Value.main(args); - } - - - @Test public void Bidi_Map(){ - Bidi_Map.main(args); - } - - @Test public void Histogram(){ - Histogram.main(args); - } - - @Test public void Lazily_Loaded_Records(){ - Lazily_Loaded_Records.main(args); - } - - @Test public void Map_Size_Counter(){ - Map_Size_Counter.main(args); - } - - @Test public void MultiMap(){ - MultiMap.main(args); - } - - @Test public void Secondary_Key(){ - Secondary_Key.main(args); - } - - @Test public void Secondary_Map(){ - Secondary_Map.main(args); - } - - @Test public void Secondary_Values(){ - Secondary_Values.main(args); - } - - @Test public void SQL_Auto_Incremental_Unique_Key(){ - SQL_Auto_Incremental_Unique_Key.main(args); - } - - @Test public void Transactions(){ - Transactions.main(args); - } - - @Test public void Transactions2(){ - Transactions2.main(args); - } - - @Test public void TreeMap_Composite_Key(){ - TreeMap_Composite_Key.main(args); - } - - @Test public void Pump_InMemory_Import_Than_Save_To_Disk(){ - Pump_InMemory_Import_Then_Save_To_Disk.main(args); - } - - - -} diff --git a/src/test/java/org/mapdb/FunTest.java b/src/test/java/org/mapdb/FunTest.java deleted file mode 100644 index 1a629d78d..000000000 --- a/src/test/java/org/mapdb/FunTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import static org.junit.Assert.*; -import static org.mapdb.Fun.*; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class FunTest { - - public int compare(int[] o1, int[] o2) { - for(int i = 0;io2[i]) return 1; - } - return 0; - } - - - final Object[] vals = new Object[]{ "A", "B", "C",}; - - @Test public void t2_equals(){ - assertEquals(new Pair("A","B"), new Pair("A","B")); - assertEquals(new Pair("A",null), new Pair("A",null)); - assertFalse(new Pair("A","B").equals(new Pair("A","C"))); - } - - @Test public void t2_compare(){ - - for(int a=0;ac || (a==c && b>d)) - assertTrue(i>0); - - } - } - } - } - } - - - - - @Test public void byte_array_comparator(){ - byte[] b1 = new byte[]{1,1}; - byte[] b1_ = new byte[]{1,1}; - byte[] b2 = new byte[]{1,2}; - byte[] blong = new byte[]{1,2,3}; - assertEquals(-1, Fun.BYTE_ARRAY_COMPARATOR.compare(b1,b2)); - assertEquals(-1, Fun.BYTE_ARRAY_COMPARATOR.compare(b2,blong)); - assertEquals(1, Fun.BYTE_ARRAY_COMPARATOR.compare(b2,b1)); - assertEquals(0, Fun.BYTE_ARRAY_COMPARATOR.compare(b1,b1)); - assertEquals(0, Fun.BYTE_ARRAY_COMPARATOR.compare(b1,b1_)); - } -} diff --git a/src/test/java/org/mapdb/HTreeMap2Test.java b/src/test/java/org/mapdb/HTreeMap2Test.java deleted file mode 100644 index c701b4c95..000000000 --- a/src/test/java/org/mapdb/HTreeMap2Test.java +++ /dev/null @@ -1,734 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.io.Serializable; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import static org.junit.Assert.*; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class HTreeMap2Test { - - Engine engine; - - DB db; - - @Before public void init2(){ - engine = DBMaker.newMemoryDB().cacheDisable().makeEngine(); - db = new DB(engine);; - } - - - @After - public void close(){ - db.close(); - } - - void printMap(HTreeMap m){ - System.out.println(toString(m.segmentRecids, engine)); - } - - static String toString(long[] rootRecids, Engine engine){ - String s = "Arrays.asList(\n"; - for(long r:rootRecids){ - s+= (r==0)?null:recursiveToString(r,"", engine); - } - //s=s.substring(0,s.length()-2); - s+=");"; - return s; - } - - protected static Serializer serializer = DBMaker.newTempHashMap().LN_SERIALIZER; - - static private String recursiveToString(long r, String prefix, Engine engine) { - prefix+=" "; - String s=""; - long[][] nn = engine.get(r, HTreeMap.DIR_SERIALIZER); - if(nn==null){ - s+=prefix+"null,\n"; - }else{ - s+= prefix+"Arrays.asList(\n"; - for(long[] n:nn){ - if(n==null){ - s+=prefix+" null,\n"; - }else{ - s+=prefix+" Arrays.asList(\n"; - for(long r2:n){ - if(r2==0){ - s+=prefix+" "+"null,\n"; - }else{ - if((r2&1)==0){ - s+=recursiveToString(r2>>>1, prefix+" ", engine); - }else{ - s+=prefix+" "+"Array.asList("; - TreeMap m = new TreeMap(); - HTreeMap.LinkedNode node = - (HTreeMap.LinkedNode) engine.get - (r2 >>> 1, serializer); - while(node!=null){ - m.put(node.key, node.value); - node = (HTreeMap.LinkedNode) engine.get(node.next, serializer); - } - for(Object k:m.keySet()){ - s+= k+","+m.get(k)+","; - } - //s=s.substring(0,s.length()-1); - s+="),\n"; - } - } - } - s+=prefix+" ),\n"; - } - } -// s=s.substring(0,s.length()-2); - s+=prefix+"),\n"; - } - return s; - } - - - @Test public void testDirSerializer() throws IOException { - - long[][] l = new long[16][]; - l[3] = new long[] {0,0,12,13,14,0,Long.MAX_VALUE,0}; - l[6] = new long[] {1,2,3,4,5,6,7,8}; - - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - HTreeMap.DIR_SERIALIZER.serialize(out,l); - - DataIO.DataInputByteBuffer in = swap(out); - - long[][] b = HTreeMap.DIR_SERIALIZER.deserialize(in, -1); - - assertEquals(null, b[0]); - assertEquals(null, b[1]); - assertEquals(null, b[2]); - assertEquals(Arrays.toString(new long[] {0,0,12,13,14,0,Long.MAX_VALUE,0}), Arrays.toString(b[3])); - assertEquals(null, b[4]); - assertEquals(null, b[5]); - assertEquals(Arrays.toString(new long[] {1,2,3,4,5,6,7,8}), Arrays.toString(b[6])); - assertEquals(null, b[7]); - - - - } - - DataIO.DataInputByteBuffer swap(DataIO.DataOutputByteArray d){ - byte[] b = d.copyBytes(); - return new DataIO.DataInputByteBuffer(ByteBuffer.wrap(b),0); - } - - - @Test public void ln_serialization() throws IOException { - HTreeMap.LinkedNode n = new HTreeMap.LinkedNode(123456, 1111L, 123L, 456L); - - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - - serializer.serialize(out, n); - - DataIO.DataInputByteBuffer in = swap(out); - - HTreeMap.LinkedNode n2 = (HTreeMap.LinkedNode) serializer.deserialize(in, -1); - - assertEquals(123456, n2.next); - assertEquals(0L, n2.expireLinkNodeRecid); - assertEquals(123L,n2.key); - assertEquals(456L,n2.value); - } - - @Test public void test_simple_put(){ - - HTreeMap m = new HTreeMap(engine,0,0,HTreeMap.preallocateSegments(engine),Serializer.BASIC, Serializer.BASIC,0,0,0,0,0,null,null,null, null,false,null); - - m.put(111L, 222L); - m.put(333L, 444L); - assertTrue(m.containsKey(111L)); - assertTrue(!m.containsKey(222L)); - assertTrue(m.containsKey(333L)); - assertTrue(!m.containsKey(444L)); - - assertEquals(222L, m.get(111L)); - assertEquals(null, m.get(222L)); - assertEquals(444l, m.get(333L)); - } - - @Test public void test_hash_collision(){ - HTreeMap m = new HTreeMap(engine,0,0,HTreeMap.preallocateSegments(engine),Serializer.BASIC, Serializer.BASIC,0,0,0,0,0,null,null,null, null,false,null){ - @Override - protected int hash(Object key) { - return 0; - } - }; - - for(long i = 0;i<20;i++){ - m.put(i,i+100); - } - - for(long i = 0;i<20;i++){ - assertTrue(m.containsKey(i)); - assertEquals(i+100, m.get(i)); - } - - m.put(11L, 1111L); - assertEquals(1111L,m.get(11L) ); - } - - @Test public void test_hash_dir_expand(){ - HTreeMap m = new HTreeMap(engine,0,0,HTreeMap.preallocateSegments(engine),Serializer.BASIC, Serializer.BASIC,0,0,0,0,0,null,null,null, null,false,null){ - @Override - protected int hash(Object key) { - return 0; - } - }; - - for(long i = 0;i< HTreeMap.BUCKET_OVERFLOW;i++){ - m.put(i,i); - } - - //segment should not be expanded - long[][] l = engine.get(m.segmentRecids[0], HTreeMap.DIR_SERIALIZER); - assertNotNull(l[0]); - assertEquals(1, l[0][0]&1); //last bite indicates leaf - for(int j=1;j<8;j++){ //all others should be null - assertEquals(0, l[0][j]); - } - long recid = l[0][0]>>>1; - - for(long i = HTreeMap.BUCKET_OVERFLOW -1; i>=0; i--){ - assertTrue(recid!=0); - HTreeMap.LinkedNode n = (HTreeMap.LinkedNode) engine.get(recid, m.LN_SERIALIZER); - assertEquals(i, n.key); - assertEquals(i, n.value); - recid = n.next; - } - - //adding one more item should trigger dir expansion to next level - m.put((long) HTreeMap.BUCKET_OVERFLOW, (long) HTreeMap.BUCKET_OVERFLOW); - - recid = m.segmentRecids[0]; - - l = engine.get(recid, HTreeMap.DIR_SERIALIZER); - assertNotNull(l[0]); - for(int j=1;j<8;j++){ //all others should be null - assertEquals(null, l[j]); - } - - assertEquals(0, l[0][0]&1); //last bite indicates leaf - for(int j=1;j<8;j++){ //all others should be zero - assertEquals(0, l[0][j]); - } - - recid = l[0][0]>>>1; - - - l = engine.get(recid, HTreeMap.DIR_SERIALIZER); - assertNotNull(l[0]); - for(int j=1;j<8;j++){ //all others should be null - assertEquals(null, l[j]); - } - - assertEquals(1, l[0][0]&1); //last bite indicates leaf - for(int j=1;j<8;j++){ //all others should be zero - assertEquals(0, l[0][j]); - } - - recid = l[0][0]>>>1; - - for(long i = 0; i<= HTreeMap.BUCKET_OVERFLOW; i++){ - assertTrue(recid!=0); - HTreeMap.LinkedNode n = (HTreeMap.LinkedNode) engine.get(recid, m.LN_SERIALIZER); - - assertNotNull(n); - assertEquals(i, n.key); - assertEquals(i, n.value); - recid = n.next; - } - - } - - - @Test public void test_delete(){ - HTreeMap m = new HTreeMap(engine,0,0,HTreeMap.preallocateSegments(engine),Serializer.BASIC, Serializer.BASIC,0,0,0,0,0,null,null,null, null,false,null){ - @Override - protected int hash(Object key) { - return 0; - } - }; - - for(long i = 0;i<20;i++){ - m.put(i,i+100); - } - - for(long i = 0;i<20;i++){ - assertTrue(m.containsKey(i)); - assertEquals(i+100, m.get(i)); - } - - - for(long i = 0;i<20;i++){ - m.remove(i); - } - - for(long i = 0;i<20;i++){ - assertTrue(!m.containsKey(i)); - assertEquals(null, m.get(i)); - } - } - - @Test public void clear(){ - HTreeMap m = new HTreeMap(engine,0,0,HTreeMap.preallocateSegments(engine),Serializer.BASIC, Serializer.BASIC,0,0,0,0,0,null,null,null, null,false,null); - for(Integer i=0;i<100;i++){ - m.put(i,i); - } - m.clear(); - assertTrue(m.isEmpty()); - assertEquals(0, m.size()); - } - - @Test //(timeout = 10000) - public void testIteration(){ - HTreeMap m = new HTreeMap(engine, 0,0,HTreeMap.preallocateSegments(engine),Serializer.BASIC,Serializer.BASIC,0,0,0,0,0,null,null,null, null,false,null){ - @Override - protected int hash(Object key) { - return (Integer) key; - } - }; - - final int max = 140; - final int inc = 111111; - - for(Integer i=0;i keys = m.keySet().iterator(); - for(Integer i=0;i vals = m.values().iterator(); - for(Integer i=inc;i1050){}; - - Thread.sleep(500); - long size = m.size(); - assertTrue(""+size,size>900 && size<=1050); - } - - - @Test public void testSingleIter(){ - Map m = DBMaker.newTempHashMap(); - m.put("aa","bb"); - - Iterator iter = m.keySet().iterator(); - assertTrue(iter.hasNext()); - assertEquals("aa",iter.next()); - assertFalse(iter.hasNext()); - } - - @Test public void testMinMaxExpiryTime(){ - HTreeMap m = db.createHashMap("test") - .expireAfterWrite(10000) - .expireAfterAccess(100000) - .make(); - long t = System.currentTimeMillis(); - assertEquals(0L, m.getMaxExpireTime()); - assertEquals(0L, m.getMinExpireTime()); - m.put("11","11"); - m.put("12","12"); - assertTrue(Math.abs(m.getMaxExpireTime()-t-10000)<300); - assertTrue(Math.abs(m.getMinExpireTime()-t-10000)<300); - - m.get("11"); - assertTrue(Math.abs(m.getMaxExpireTime()-t-100000)<300); - assertTrue(Math.abs(m.getMinExpireTime()-t-10000)<300); - m.remove("11"); - m.remove("12"); - assertEquals(0L, m.getMaxExpireTime()); - assertEquals(0L, m.getMinExpireTime()); - } - - @Test (timeout = 20000) - public void cache_load_time_expire(){ - DB db = - DBMaker.newMemoryDB() - .sizeLimit(1) - .transactionDisable() - .cacheDisable() - .make(); - - HTreeMap m = db.createHashMap("test") - //.expireMaxSize(11000000) - .expireAfterWrite(100) - .make(); - long time = System.currentTimeMillis(); - long counter = 0; - while(time+5000>System.currentTimeMillis()){ - m.put(counter++,counter++); - } - m.clear(); - } - - @Test(timeout = 20000) - public void cache_load_size_expire(){ - DB db = DBMaker.newMemoryDB() - .sizeLimit(1) - .transactionDisable() - .make(); - - HTreeMap m = db.createHashMap("test") - //.expireMaxSize(11000000) - .expireMaxSize(10000) - .make(); - long time = System.currentTimeMillis(); - long counter = 0; - while(time+5000>System.currentTimeMillis()){ - m.put(counter++,counter++); -// if(counter%1000<2) System.out.println(m.size()); - } - m.clear(); - } - - @Test public void divMod8(){ - for(int i= 0;i<1000000;i++){ - assertEquals(i/8,i>>HTreeMap.DIV8); - assertEquals(i%8,i&HTreeMap.MOD8); - } - } - - - @Test public void hasher(){ - HTreeMap m = - DBMaker.newMemoryDB().make() - .createHashMap("test") - .hasher(Hasher.INT_ARRAY) - .make(); - - for(int i=0;i<1e5;i++){ - m.put(new int[]{i,i,i},i); - } - for(Integer i=0;i<1e5;i++){ - assertEquals(i,m.get(new int[]{i,i,i})); - } - - } - - @Test public void mod_listener_lock(){ - DB db = DBMaker.newMemoryDB().make(); - final HTreeMap m = db.getHashMap("name"); - - final int seg = m.hash("aa")>>>28; - final AtomicInteger counter = new AtomicInteger(); - - m.modificationListenerAdd(new Bind.MapListener() { - @Override - public void update(Object key, Object oldVal, Object newVal) { - for (int i = 0; i < m.segmentLocks.length; i++) { - assertEquals(seg == i, m.segmentLocks[i].isWriteLockedByCurrentThread()); - } - counter.incrementAndGet(); - } - }); - - - m.put("aa","aa"); - m.put("aa", "bb"); - m.remove("aa"); - - - m.put("aa","aa"); - m.remove("aa","aa"); - m.putIfAbsent("aa","bb"); - m.replace("aa","bb","cc"); - m.replace("aa","cc"); - - assertEquals(8, counter.get()); - } - - @Test - public void test_iterate_and_remove(){ - final long max= (long) 1e5; - - Set m = DBMaker.newMemoryDB().cacheDisable().transactionDisable().make().getHashSet("test"); - - for(long i=0;i map = db.createHashMap("cache").expireMaxSize(MAX_ITEM_SIZE).counterEnable() - .expireAfterWrite(EXPIRE_TIME, TimeUnit.SECONDS).expireStoreSize(MAX_GB_SIZE).make(); - - i set EXPIRE_TIME = 216000 - - but the data was expired right now,the expire time is not 216000s, it seems there is a bug for expireAfterWrite. - - if i call expireAfterAccess ,everything seems ok. - - */ - @Test public void expireAfterWrite() throws InterruptedException { - //NOTE this test has race condition and may fail under heavy load. - //TODO increase timeout and move into integration tests. - - DB db = DBMaker.newMemoryDB().transactionDisable().make(); - - int MAX_ITEM_SIZE = (int) 1e7; - int EXPIRE_TIME = 3; - double MAX_GB_SIZE = 1e7; - - Map m = db.createHashMap("cache").expireMaxSize(MAX_ITEM_SIZE).counterEnable() - .expireAfterWrite(EXPIRE_TIME, TimeUnit.SECONDS).expireStoreSize(MAX_GB_SIZE).make(); - - for(int i=0;i<1000;i++){ - m.put(i,i); - } - Thread.sleep(2000); - - for(int i=0;i<500;i++){ - m.put(i,i+1); - } - assertEquals(m.size(),1000); - - Thread.sleep(2000); - - assertEquals(m.size(),500); - } - - - public static class AA implements Serializable{ - final int val; - - public AA(int val) { - this.val = val; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof AA && ((AA)obj).val == val; - } - } - - - @Test(expected = IllegalArgumentException.class) - public void inconsistentHash(){ - DB db = DBMaker.newMemoryDB() - .transactionDisable() - .make(); - - HTreeMap m = db.createHashMap("test") - - .make(); - - for(int i=0;i<1e5;i++){ - m.put(new AA(i),i); - } - } - - @Test - public void test() - { - DB db = DBMaker.newMemoryDB().make(); - Map map = db.getHashMap("map", new Fun.Function1() { - @Override - public Integer run(String s) { - return Integer.MIN_VALUE; - } - }); - Integer v1 = map.get("s1"); - assertEquals(Integer.valueOf(Integer.MIN_VALUE), v1); - } - -} - diff --git a/src/test/java/org/mapdb/HTreeMap3Test.java b/src/test/java/org/mapdb/HTreeMap3Test.java deleted file mode 100644 index e1ece7f64..000000000 --- a/src/test/java/org/mapdb/HTreeMap3Test.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright 2010 Cees De Groot, Alex Boisvert, Jan Kotek - * - * 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 - * - * http://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. - ******************************************************************************/ -package org.mapdb; - -import org.junit.After; - -import java.util.concurrent.ConcurrentMap; - -public class HTreeMap3Test extends ConcurrentMapInterfaceTest { - - public HTreeMap3Test() { - super(false, false, true, true, true, true,true); - } - - StoreDirect r; - - @Override - protected void setUp() throws Exception { - r = new StoreDirect(null); - } - - - @Override - protected void tearDown() throws Exception { - r.close(); - } - - @Override - protected Integer getKeyNotInPopulatedMap() throws UnsupportedOperationException { - return -100; - } - - @Override - protected String getValueNotInPopulatedMap() throws UnsupportedOperationException { - return "XYZ"; - } - - @Override - protected String getSecondValueNotInPopulatedMap() throws UnsupportedOperationException { - return "AAAA"; - } - - @Override - protected ConcurrentMap makeEmptyMap() throws UnsupportedOperationException { - return new HTreeMap(r,0,0, HTreeMap.preallocateSegments(r), Serializer.BASIC, Serializer.BASIC,0,0,0,0,0,null,null,null,null,false,null); - } - - @Override - protected ConcurrentMap makePopulatedMap() throws UnsupportedOperationException { - ConcurrentMap map = makeEmptyMap(); - for (int i = 0; i < 100; i++) - map.put(i, "aa" + i); - return map; - } - -} diff --git a/src/test/java/org/mapdb/HTreeSetTest.java b/src/test/java/org/mapdb/HTreeSetTest.java deleted file mode 100644 index 479b04e08..000000000 --- a/src/test/java/org/mapdb/HTreeSetTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 - * - * http://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. - */ - -package org.mapdb; - - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collections; -import java.util.Iterator; -import java.util.Set; - -import static junit.framework.TestCase.assertFalse; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - - -/** - * Tests for HashSet which comes with JDBM. Original code comes from Apache Harmony, - * Modified by Jan Kotek for use in JDBM - */ -@SuppressWarnings({"unchecked","rawtypes"}) -public class HTreeSetTest{ - - Engine engine; - - Set hs; - - static Object[] objArray; - - static { - objArray = new Object[1000]; - for (int i = 0; i < objArray.length; i++) - objArray[i] = i; - } - - @Before public void init(){ - engine = new StoreDirect(null); - hs = new HTreeMap(engine, 0,0,HTreeMap.preallocateSegments(engine),Serializer.BASIC,null,0,0,0,0,0,null,null,null, null,false,null).keySet(); - Collections.addAll(hs, objArray); - } - - @Test public void test_Constructor() { - // Test for method java.util.HashSet() - Set hs2 = new HTreeMap(engine, 0,0,HTreeMap.preallocateSegments(engine),Serializer.BASIC,null,0,0,0,0,0,null,null,null, null,false,null).keySet(); - assertEquals("Created incorrect HashSet", 0, hs2.size()); - } - - @After - public void close(){ - engine.close(); - } - - - @Test public void test_addLjava_lang_Object() { - // Test for method boolean java.util.HashSet.add(java.lang.Object) - int size = hs.size(); - hs.add(8); - assertTrue("Added element already contained by set", hs.size() == size); - hs.add(-9); - assertTrue("Failed to increment set size after add", - hs.size() == size + 1); - assertTrue("Failed to add element to set", hs.contains(new Integer(-9))); - } - - @Test public void test_clear() { - // Test for method void java.util.HashSet.clear() - Set orgSet = new java.util.HashSet(hs); - hs.clear(); - Iterator i = orgSet.iterator(); - assertEquals("Returned non-zero size after clear", 0, hs.size()); - while (i.hasNext()) - assertTrue("Failed to clear set", !hs.contains(i.next())); - } - - - @Test public void test_containsLjava_lang_Object() { - // Test for method boolean java.util.HashSet.contains(java.lang.Object) - assertTrue("Returned false for valid object", hs.contains(objArray[90])); - assertTrue("Returned true for invalid Object", !hs - .contains(-111111)); - - } - - @Test public void test_isEmpty() { - // Test for method boolean java.util.HashSet.isEmpty() - assertTrue("Empty set returned false", new HTreeMap(engine, 0,0,HTreeMap.preallocateSegments(engine),Serializer.BASIC,null,0,0,0,0,0,null,null,null,null,false,null).keySet().isEmpty()); - assertTrue("Non-empty set returned true", !hs.isEmpty()); - } - - @Test public void test_iterator() { - // Test for method java.util.Iterator java.util.HashSet.iterator() - Iterator i = hs.iterator(); - int x = 0; - while (i.hasNext()) { - assertTrue("Failed to iterate over all elements", hs.contains(i - .next())); - ++x; - } - assertTrue("Returned iteration of incorrect size", hs.size() == x); - - } - - @Test public void test_removeLjava_lang_Object() { - // Test for method boolean java.util.HashSet.remove(java.lang.Object) - int size = hs.size(); - hs.remove(new Integer(98)); - assertTrue("Failed to remove element", !hs.contains(new Integer(98))); - assertTrue("Failed to decrement set size", hs.size() == size - 1); - - } - - @Test public void test_size() { - // Test for method int java.util.HashSet.size() - assertTrue("Returned incorrect size", hs.size() == (objArray.length)); - hs.clear(); - assertEquals("Cleared set returned non-zero size", 0, hs.size()); - } - - - - @Test public void issue116_isEmpty(){ - Set s = DBMaker.newFileDB(UtilsTest.tempDbFile()) - .transactionDisable() - .make() - .getHashSet("name"); - assertTrue(s.isEmpty()); - assertEquals(0,s.size()); - s.add("aa"); - assertEquals(1,s.size()); - assertFalse(s.isEmpty()); - s.remove("aa"); - assertTrue(s.isEmpty()); - assertEquals(0,s.size()); - } - -} diff --git a/src/test/java/org/mapdb/Issue112Test.java b/src/test/java/org/mapdb/Issue112Test.java deleted file mode 100644 index e5ae06835..000000000 --- a/src/test/java/org/mapdb/Issue112Test.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class Issue112Test { - - - @Test(timeout=10000) - public void testDoubleCommit() throws Exception { - final DB myTestDataFile = DBMaker.newFileDB(UtilsTest.tempDbFile()) - .checksumEnable() - .make(); - myTestDataFile.commit(); - myTestDataFile.commit(); - - long recid = myTestDataFile.engine.put("aa",Serializer.STRING_NOSIZE); - myTestDataFile.commit(); - - assertEquals("aa",myTestDataFile.engine.get(recid, Serializer.STRING_NOSIZE)); - } - - } diff --git a/src/test/java/org/mapdb/Issue114Test.java b/src/test/java/org/mapdb/Issue114Test.java deleted file mode 100644 index 96512f6ea..000000000 --- a/src/test/java/org/mapdb/Issue114Test.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -public class Issue114Test { - - @Test - public void test(){ - DB db = DBMaker.newTempFileDB() - //.randomAccessFileEnable() - .transactionDisable().make(); - db.getCircularQueue("test"); - } -} diff --git a/src/test/java/org/mapdb/Issue132Test.java b/src/test/java/org/mapdb/Issue132Test.java deleted file mode 100644 index 00b2138cc..000000000 --- a/src/test/java/org/mapdb/Issue132Test.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.mapdb; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.Iterator; -import java.util.Set; - -public class Issue132Test { - - - static void expectCount(Set set, int count) { - Assert.assertEquals(count, count(set.iterator())); - } - - static int count(final Iterator iterator) { - int counter = 0; - while (iterator.hasNext()) { - iterator.next(); - counter++; - } - return counter; - } - - @Test(timeout=50000) - public void test_full() { - long id= 0; - for(int count = 0; count < 50; count++) { - - - DB db = DBMaker.newMemoryDB().cacheDisable() - .checksumEnable().make(); - - - - Set set = db.getHashSet("test"); - db.commit(); - - for (int i = 0; i < count; i++) { - set.add(id++); - db.commit(); - } - expectCount(set, count); - - for (int i = 0; i < count; i++) { - set.add(id++); - db.rollback(); - } - expectCount(set, count); - - for (int i = 0; i < count; i++) { - set.add(id++); - } - expectCount(set, count * 2); - db.commit(); - expectCount(set, count * 2); - - db.close(); - - } - } - - @Test(timeout=10000) - public void test_isolate() { - long id= 0; - int count = 18; - - - DB db = DBMaker.newMemoryDB().cacheDisable() - .checksumEnable().make(); - - - Set set = db.getHashSet("test"); - db.commit(); - - for (int i = 0; i < count; i++) { - set.add(id++); - } - db.commit(); - expectCount(set, count); - - for (int i = 0; i < count; i++) { - set.add(id++); - } - db.rollback(); - expectCount(set, count); - - for (int i = 0; i < count; i++) { - set.add(id++); - } - expectCount(set, count * 2); - db.commit(); - expectCount(set, count * 2); - - db.close(); - - } - - -} diff --git a/src/test/java/org/mapdb/Issue148Test.java b/src/test/java/org/mapdb/Issue148Test.java deleted file mode 100644 index 72934b079..000000000 --- a/src/test/java/org/mapdb/Issue148Test.java +++ /dev/null @@ -1,179 +0,0 @@ -package org.mapdb; - - - - -import org.junit.Test; - -import java.io.*; -import java.util.Set; - -import static org.junit.Assert.assertEquals; - -public class Issue148Test { - - @Test public void repeated_update(){ - File mapdbFile = UtilsTest.tempDbFile(); - - String str = UtilsTest.randomString(1000); - Engine engine = DBMaker.newAppendFileDB(mapdbFile).closeOnJvmShutdown().cacheDisable().makeEngine(); - long recid = engine.put(str,Serializer.STRING_NOSIZE); - engine.commit(); - engine.close(); - - for(int i=10;i<100;i++){ - engine = DBMaker.newAppendFileDB(mapdbFile).closeOnJvmShutdown().cacheDisable().makeEngine(); - assertEquals(str, engine.get(recid, Serializer.STRING_NOSIZE)); - str = UtilsTest.randomString(i); - engine.update(recid,str,Serializer.STRING_NOSIZE); - assertEquals(str, engine.get(recid, Serializer.STRING_NOSIZE)); - engine.commit(); - engine.close(); - } - - - } - - @Test - public void test(){ - - // 1 : Create HTreeMap, put some values , Commit and Close; - File mapdbFile = UtilsTest.tempDbFile(); - DB mapdb = DBMaker.newAppendFileDB(mapdbFile).closeOnJvmShutdown().cacheDisable().make(); - - Serializer valueSerializer = new CustomValueSerializer(); - HTreeMap users = mapdb.createHashMap("users").counterEnable().make(); - users.put("jhon", new CustomValue("jhon", 32)); - users.put("mike", new CustomValue("mike", 30)); - mapdb.commit(); - - System.out.println("Create and Fisrt Put [\"jhon\"->32, \"mike\"->30]"); - dumpUserDB(users); - - users.replace("mike", new CustomValue("mike", 33)); - mapdb.commit(); - - System.out.println("Replace Before Close : [\"mike\"->33] looks as works"); - dumpUserDB(users); - - mapdb.close(); - - - // 2 : Open HTreeMap, replace some values , Commit and Close; - mapdb = DBMaker.newAppendFileDB(mapdbFile).closeOnJvmShutdown().cacheDisable().make(); - users = mapdb.getHashMap("users"); - - System.out.println("Just Reopen : all values ar good"); - dumpUserDB(users); - - CustomValue old = users.replace("jhon", new CustomValue("jhon", 31)); - assertEquals(32, old.age); - assertEquals("jhon", old.name); - - assertEquals(31, users.get("jhon").age); - assertEquals("jhon", users.get("jhon").name); - - mapdb.commit(); - assertEquals(31, users.get("jhon").age); - assertEquals("jhon", users.get("jhon").name); - - System.out.println("Do Replacement on Reopen : [\"jhon\"->31] looks as works"); - dumpUserDB(users); - mapdb.close(); - - - // 3 : Open HTreeMap, Dump - mapdb = DBMaker.newAppendFileDB(mapdbFile).closeOnJvmShutdown().cacheDisable().make(); - users = mapdb.getHashMap("users"); - - System.out.println("But final value is not changed"); - dumpUserDB(users); - assertEquals(31, users.get("jhon").age); - assertEquals("jhon", users.get("jhon").name); - - mapdb.close(); - } - - public static void dumpUserDB(HTreeMap users){ - - Set keyset = users.keySet(); - if(keyset==null){ - return; - } - - for( String key : keyset ){ - CustomValue cv = users.get(key); - System.out.format("%s(%b) : %d\n", key, key.equals(cv.name), cv.age); - } - - System.out.println(""); - } - - /** Custom Value and Serializer **/ - - public static class CustomValue implements Serializable { - - private static final long serialVersionUID = -7585177565368493580L; - final String name; - final int age; - - public CustomValue(String name, int age){ - - this.name = name; - this.age = age; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + age; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CustomValue other = (CustomValue) obj; - if (age != other.age) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } - } - - public static class CustomValueSerializer implements Serializer, Serializable { - - private static final long serialVersionUID = -6987588810823227467L; - - public void serialize(DataOutput out, CustomValue value) throws IOException { - - out.writeUTF(value.name); - out.writeInt(value.age); - } - - public CustomValue deserialize(DataInput in, int available) - throws IOException { - - return new CustomValue( in.readUTF(), in.readInt() ); - } - - @Override - public int fixedSize() { - return -1; - } - - } - - -} diff --git a/src/test/java/org/mapdb/Issue150Test.java b/src/test/java/org/mapdb/Issue150Test.java deleted file mode 100644 index 2ea85916a..000000000 --- a/src/test/java/org/mapdb/Issue150Test.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.io.Serializable; -import java.util.Map; - -public class Issue150Test { - - @Test - public void test() { - // TxMaker txMaker = DBMaker.newFileDB(new File("/tmp/mapdb.test")) - // .closeOnJvmShutdown().asyncWriteDisable().makeTxMaker(); - TxMaker txMaker = DBMaker.newMemoryDB().closeOnJvmShutdown() - .makeTxMaker(); - - DB db = txMaker.makeTx(); - - EntityA x = new EntityA(); - x.setId(126l); - x.setName("nameXXX"); - - Serializer valueSerializer = new CustomSerializer(); - Map map = db.createHashMap("entitya").valueSerializer(valueSerializer).make(); - - map.put(x.getId(), x); - - db.commit(); - - EntityA y = (EntityA) txMaker.makeTx().getHashMap("entitya") - .get(x.getId()); - System.out.println(x.equals(y)); - - txMaker.close(); - } - - private static final class CustomSerializer implements - Serializer, Serializable { - - @Override - public void serialize(DataOutput out, EntityA value) throws IOException { - out.writeLong(value.getId()); - out.writeUTF(value.getName()); - } - - @Override - public EntityA deserialize(DataInput in, int available) - throws IOException { - - EntityA a = new EntityA(); - a.setId(in.readLong()); - a.setName(in.readUTF()); - return a; - } - - @Override - public int fixedSize() { - return -1; - } - - } - - public static class EntityA implements Serializable { - - private Long id; - - private String name; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - EntityA other = (EntityA) obj; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } - - } - -} diff --git a/src/test/java/org/mapdb/Issue154Test.java b/src/test/java/org/mapdb/Issue154Test.java deleted file mode 100644 index cf70bfff7..000000000 --- a/src/test/java/org/mapdb/Issue154Test.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import java.util.Map; - -import static org.junit.Assert.assertEquals; - -public class Issue154Test { - - @Test - public void HTreeMap(){ - TxMaker txMaker = DBMaker.newMemoryDB().makeTxMaker(); - - /* Add the item */ - - DB db1 = txMaker.makeTx(); - Map map1 = db1.getHashMap("simple"); - map1.put("a", "b"); - db1.commit(); - - /* Remove the item */ - - DB db2 = txMaker.makeTx(); - Map map2 = db2.getHashMap("simple"); - - // Make sure the item is still there - assertEquals("b",map2.get("a")); - map2.remove("a"); - assertEquals(null,map2.get("a")); - // ROLLBACK the removal (in theory) - db2.rollback(); - - /* Check for the rolled back item */ - - DB db3 = txMaker.makeTx(); - Map map3 = db3.getHashMap("simple"); - - // *************** - // THIS IS WHERE IT FAILS, but the object should be the same, since it the remove was rolled back - // *************** - - assertEquals("b",map3.get("a")); - - db3.close(); - } - - @Test public void simple(){ - TxMaker txMaker = DBMaker.newMemoryDB().makeTxMaker(); - Engine engine = txMaker.makeTx().getEngine(); - long recid = engine.put("aa",Serializer.STRING_NOSIZE); - engine.commit(); - engine = txMaker.makeTx().getEngine(); - assertEquals("aa",engine.get(recid,Serializer.STRING_NOSIZE)); - engine.delete(recid,Serializer.STRING_NOSIZE); - assertEquals(null,engine.get(recid,Serializer.STRING_NOSIZE)); - engine.rollback(); - engine = txMaker.makeTx().getEngine(); - assertEquals("aa",engine.get(recid,Serializer.STRING_NOSIZE)); - - } - - @Test - public void BTreeMap(){ - TxMaker txMaker = DBMaker.newMemoryDB().makeTxMaker(); - - /* Add the item */ - - DB db1 = txMaker.makeTx(); - Map map1 = db1.getTreeMap("simple"); - map1.put("a", "b"); - db1.commit(); - - /* Remove the item */ - - DB db2 = txMaker.makeTx(); - Map map2 = db2.getTreeMap("simple"); - - // Make sure the item is still there - assertEquals("b",map2.get("a")); - map2.remove("a"); - assertEquals(null,map2.get("a")); - // ROLLBACK the removal (in theory) - db2.rollback(); - - /* Check for the rolled back item */ - - DB db3 = txMaker.makeTx(); - Map map3 = db3.getTreeMap("simple"); - - // *************** - // THIS IS WHERE IT FAILS, but the object should be the same, since it the remove was rolled back - // *************** - - assertEquals("b",map3.get("a")); - - db3.close(); - } -} diff --git a/src/test/java/org/mapdb/Issue157Test.java b/src/test/java/org/mapdb/Issue157Test.java deleted file mode 100644 index a3b4c88da..000000000 --- a/src/test/java/org/mapdb/Issue157Test.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.Map; - -import static org.junit.Assert.assertTrue; - -public class Issue157Test { - - @Test - public void concurrent_BTreeMap() throws InterruptedException { - DBMaker dbMaker = DBMaker.newMemoryDB().cacheDisable(); - DB db = dbMaker.make(); - final BTreeMap map = db.getTreeMap("COL_2"); - map.clear(); - - Thread t1 = new Thread() { - public void run() { - for(int i=0; i<=10000; i++) { - map.put(i, "foo"); - } - } - }; - - Thread t2 = new Thread() { - public void run() { - for(int i=10000; i>=0; i--) { - map.put(i, "bar"); - } - } - }; - - t1.start(); - t2.start(); - - t1.join(); - t2.join(); - -// map.printTreeStructure(); - - for(Map.Entry entry : map.entrySet()) { -// System.out.println(entry.getKey() + " => " + entry.getValue()); - assertTrue(""+entry.getKey(),"bar".equals(entry.getValue())||"foo".equals(entry.getValue())); - } - - - - } -} diff --git a/src/test/java/org/mapdb/Issue162Test.java b/src/test/java/org/mapdb/Issue162Test.java deleted file mode 100644 index c19eec2f1..000000000 --- a/src/test/java/org/mapdb/Issue162Test.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.*; -import java.util.Map; - -import static org.junit.Assert.assertTrue; - - -public class Issue162Test { - - public static class MyValue implements Serializable { - private String string; - - public MyValue(String string) { - this.string = string; - } - - @Override - public String toString() { - return "MyValue{" + "string='" + string + '\'' + '}'; - } - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof MyValue)) return false; - - MyValue myValue = (MyValue) o; - if (!string.equals(myValue.string)) return false; - return true; - } - - - @Override - public int hashCode() { - return string.hashCode(); - } - } - - public static class MyValueSerializer implements Serializable, Serializer { - - @Override - public void serialize(DataOutput out, MyValue value) throws IOException { - assertTrue(value != null); - System.out.println("Custom serializer called with '" + value + "'"); - out.writeUTF(value.string); - } - - @Override - public MyValue deserialize(DataInput in, int available) throws IOException { - String s = in.readUTF(); - return new MyValue(s); - } - - @Override - public int fixedSize() { - return -1; - } - - } - - private static void printEntries(Map map) { - System.out.println("Reading back data"); - for (Map.Entry entry : map.entrySet()) { - System.out.println("Entry id = " + entry.getKey() + ", contents = " + entry.getValue().toString()); - } - } - - File path = UtilsTest.tempDbFile(); - - @Test public void testHashMap() { - System.out.println("--- Testing HashMap with custom serializer"); - - DB db = DBMaker.newFileDB(path).make(); - Map map = db.createHashMap("map") - .valueSerializer(new MyValueSerializer()) - .make(); - db.commit(); - - System.out.println("Putting and committing data"); - map.put(1L, new MyValue("one")); - map.put(2L, new MyValue("two")); - db.commit(); - - System.out.println("Closing and reopening db"); - db.close(); - map = null; - - db = DBMaker.newFileDB(path).make(); - map = db.getHashMap("map"); - - printEntries(map); - } - - @Test public void testBTreeMap() { - System.out.println("--- Testing BTreeMap with custom serializer"); - - DB db = DBMaker.newFileDB(path).make(); - Map map = db.createTreeMap("map") - .valueSerializer(new MyValueSerializer()) - .make(); - db.commit(); - - System.out.println("Putting and committing data"); - map.put(1L, new MyValue("one")); - map.put(2L, new MyValue("two")); - db.commit(); - - System.out.println("Closing and reopening db"); - db.close(); - map = null; - - db = DBMaker.newFileDB(path).make(); - map = db.getTreeMap("map"); - - printEntries(map); - } - -} diff --git a/src/test/java/org/mapdb/Issue164Test.java b/src/test/java/org/mapdb/Issue164Test.java deleted file mode 100644 index 534afe2d2..000000000 --- a/src/test/java/org/mapdb/Issue164Test.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.Serializable; -import java.util.HashSet; - -import static org.junit.Assert.assertTrue; - -public class Issue164Test { - - public static class Scenario implements Serializable { - private static final long serialVersionUID = 1L; - protected String id = null; - protected String brief = null; - protected String headNodeId = null; - protected HashSet nodeIdSet = null; - public Scenario() { - id = Long.toHexString(System.nanoTime()); - brief = null; - headNodeId = null; - nodeIdSet = null; - } - public void setId(String arg_id) { - synchronized(this) { - id = arg_id; - } - } - public String getId() { - synchronized(this) { - return id; - } - } - public void setBrief(String arg_brief) { - synchronized(this) { - brief = arg_brief; - } - } - public String getBrief() { - synchronized(this) { - return brief; - } - } - public String getHeadNodeId() { - synchronized(this) { - return headNodeId; - } - } - public void setHeadNodeId(String arg_header_node_id) { - synchronized(this) { - headNodeId = arg_header_node_id; - if (!nodeIdSet.contains(arg_header_node_id)) - nodeIdSet.add(arg_header_node_id); - } - } - public void addConversationNodeId(String arg_conversation_node_id) throws Exception { - synchronized(this) { - if (headNodeId == null) { - headNodeId = arg_conversation_node_id; - nodeIdSet.add(arg_conversation_node_id); - } - else - throw new Exception(); - } // of synchronized(this) - } - public void removeConversationNodeId(String arg_conversation_node_id) { - synchronized(this) { - if (headNodeId != null) { - nodeIdSet.remove(arg_conversation_node_id); - if (arg_conversation_node_id.equals(headNodeId)) - headNodeId = null; // the set is empty now - } - } // of synchronized(this) - } - } - - - @Test - public void main() { - int rc = 0; - BTreeMap map=null; - try { - DB db = DBMaker.newMemoryDB() - .closeOnJvmShutdown() - .make(); -// the following test shows that the db is opened if it always exists - map = db.getTreeMap("test"); - if (!map.containsKey("t1")) { - map.put("t1", new Scenario()); - db.commit(); - } - rc = 1; - } catch(Exception ex) { - rc = -1; - } - assertTrue(map.get("t1")!=null); - assertTrue(rc > 0); - - } -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/Issue170Test.java b/src/test/java/org/mapdb/Issue170Test.java deleted file mode 100644 index e4d630be4..000000000 --- a/src/test/java/org/mapdb/Issue170Test.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.Map; -import java.util.UUID; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class Issue170Test { - - @Test - public void test(){ - Map m = DBMaker.newMemoryDB() - .compressionEnable() - .transactionDisable() - .make().createTreeMap("test").make(); - for(int i=0;i<1e5;i++){ - m.put(UUID.randomUUID().toString(),UUID.randomUUID().toString()); - } - - } -} diff --git a/src/test/java/org/mapdb/Issue183Test.java b/src/test/java/org/mapdb/Issue183Test.java deleted file mode 100644 index 6a2f2012c..000000000 --- a/src/test/java/org/mapdb/Issue183Test.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.*; -import java.util.Map; - -import static org.junit.Assert.assertEquals; - -public class Issue183Test { - - @Test - public void main(){ - - File f = UtilsTest.tempDbFile(); - - Map map1; - - TxMaker txMaker = DBMaker - .newFileDB(f) - .closeOnJvmShutdown() - .cacheDisable() - .makeTxMaker(); - - DB db = txMaker.makeTx(); - - map1 = db.createTreeMap("map1") - .valueSerializer(new StringSerializer()) - .makeOrGet(); - - map1.put("foo", "bar"); - db.commit(); - db.close(); - txMaker.close(); - - - txMaker = DBMaker - .newFileDB(f) - .closeOnJvmShutdown() - .cacheDisable() - .makeTxMaker(); - - db = txMaker.makeTx(); - - map1 = db.createTreeMap("map1") - .valueSerializer(new StringSerializer()) - .makeOrGet(); - - assertEquals("bar", map1.get("foo")); - map1.put("foo2", "bar2"); - db.commit(); - db.close(); - txMaker.close(); - - } - - private static final class StringSerializer implements Serializer, Serializable { - - private static final long serialVersionUID = -8356516782418439492L; - - @Override - public void serialize(DataOutput out, String value) throws IOException { - out.writeUTF(value); - } - - @Override - public String deserialize(DataInput in, int available) throws IOException { - return in.readUTF(); - } - - @Override - public int fixedSize() { - return -1; - } - - } -} diff --git a/src/test/java/org/mapdb/Issue198Test.java b/src/test/java/org/mapdb/Issue198Test.java deleted file mode 100644 index 60182a5dc..000000000 --- a/src/test/java/org/mapdb/Issue198Test.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - - -public class Issue198Test { - - @Test public void main() { - - DB db = DBMaker.newFileDB(UtilsTest.tempDbFile()) - .closeOnJvmShutdown() - //.randomAccessFileEnable() - .make(); - BTreeMap map = db.createTreeMap("testmap").makeOrGet(); - for(int i = 1; i <= 3000; ++i) - map.put(i, i); - db.commit(); - db.close(); - - } -} diff --git a/src/test/java/org/mapdb/Issue237Test.java b/src/test/java/org/mapdb/Issue237Test.java deleted file mode 100644 index 2f8bba385..000000000 --- a/src/test/java/org/mapdb/Issue237Test.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.File; -import java.util.concurrent.BlockingQueue; - -import static org.junit.Assert.assertEquals; - - -public class Issue237Test { - - File file = UtilsTest.tempDbFile(); - - - @Test - public void testReopenAsync() throws InterruptedException { - DB database = DBMaker.newFileDB( file ).asyncWriteEnable().make(); - testQueue( database ); - - database = DBMaker.newFileDB( file ).asyncWriteEnable().make(); - testQueue( database ); - } - - @Test - public void testReopenSync() throws InterruptedException { - file.delete(); - - DB database = DBMaker.newFileDB( file ).make(); - testQueue( database ); - - database = DBMaker.newFileDB( file ).make(); - testQueue( database ); - } - - private void testQueue( DB database ) throws InterruptedException { - BlockingQueue queue = database.getQueue( "test-queue" ); - queue.add( "test-value" ); - database.commit(); - assertEquals(queue.take(), "test-value"); - database.commit(); - database.close(); - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/Issue241.java b/src/test/java/org/mapdb/Issue241.java deleted file mode 100644 index 2721e0875..000000000 --- a/src/test/java/org/mapdb/Issue241.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.File; -import java.io.Serializable; -import java.util.Map; - -public class Issue241 -{ - @Test - public void main() - { - DB db = getDb(); - final String mapName = "map"; //$NON-NLS-1$ - Map map = db.createTreeMap(mapName).make(); -// db.createTreeMap(mapName) -// .valueSerializer(new CustomSerializer()).make(); - map.put(1L, new CustomClass("aString", 1001L)); //$NON-NLS-1$ - db.commit(); - db.close(); - - db = getDb(); - map = db.getTreeMap(mapName); - map.get(1L); - } - - private static DB getDb() - { - final File dbFile = UtilsTest.tempDbFile(); - return DBMaker.newAppendFileDB(dbFile).make(); - } - - private static final class CustomClass implements Serializable - { - private final String aString; - private final Long aLong; - - private CustomClass(String aString, Long aLong) - { - this.aString = aString; - this.aLong = aLong; - } - - private String getaString() - { - return aString; - } - - private Long getaLong() - { - return aLong; - } - } - -// public static final class CustomSerializer implements Serializer, Serializable -// { -// @Override -// public void serialize(DataOutput out, CustomClass value) throws IOException -// { -// out.writeLong(value.getaLong()); -// final byte[] stringBytes = value.getaString().getBytes(); -// out.writeInt(stringBytes.length); -// out.write(stringBytes); -// } -// -// @Override -// public CustomClass deserialize(DataInput in, int available) throws IOException -// { -// final Long theLong = in.readLong(); -// final int stringBytesLength = in.readInt(); -// final byte[] stringBytes = new byte[stringBytesLength]; -// in.readFully(stringBytes); -// return new CustomClass(new String(stringBytes), theLong); -// } -// } -} diff --git a/src/test/java/org/mapdb/Issue247Test.java b/src/test/java/org/mapdb/Issue247Test.java deleted file mode 100644 index e473e2ebb..000000000 --- a/src/test/java/org/mapdb/Issue247Test.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import java.io.File; -import java.util.Map; - -public class Issue247Test { - - private Map getMap(DB db){ - return db.createTreeMap("test") - .counterEnable() - .valuesOutsideNodesEnable() - .makeOrGet(); - } - - - @Test - public void test(){ - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f) - .transactionDisable() - .make(); - - getMap(db); - //db.commit(); - - db.close(); - - db = DBMaker.newFileDB(f) - .readOnly() - .make(); - getMap(db).size(); - } -} diff --git a/src/test/java/org/mapdb/Issue249Test.java b/src/test/java/org/mapdb/Issue249Test.java deleted file mode 100644 index e37e4967e..000000000 --- a/src/test/java/org/mapdb/Issue249Test.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.Serializable; -import java.util.Map; - - -public class Issue249Test { - - @Test - public void main() { - TxMaker txMaker = DBMaker.newMemoryDB().closeOnJvmShutdown() - .makeTxMaker(); - DB db = txMaker.makeTx(); - - UploadInfo x = new UploadInfo(); - x.setId(1L); - x.setTitle("nameXXX"); - - Map map = db.getTreeMap(UploadInfo.class.getName()); - map.put(x.getId(), x); - - db = commit(db); - db = rollback(db); - - DB db2 = txMaker.makeTx(); - Map map2 = db2.getTreeMap(UploadInfo.class.getName()); - map2.get(x.getId()); - - txMaker.close(); - } - - private static DB commit(DB db) { - if (db != null && !db.isClosed()) - db.commit(); - // db = null; - return db; - } - - private static DB rollback(DB db) { - if (db != null && !db.isClosed()) { - try { - db.rollback(); - } catch (Exception e) { - } - } - // db = null; - return db; - } - - @SuppressWarnings("serial") - public static class UploadInfo implements Serializable { - - private Long id; - private String slug; - private String zipCode; - private String www; - private String text; - private String title; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getSlug() { - return slug; - } - - public void setSlug(String slug) { - this.slug = slug; - } - - public String getZipCode() { - return zipCode; - } - - public void setZipCode(String zipCode) { - this.zipCode = zipCode; - } - - public String getWww() { - return www; - } - - public void setWww(String www) { - this.www = www; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/Issue254Test.java b/src/test/java/org/mapdb/Issue254Test.java deleted file mode 100644 index c08d84970..000000000 --- a/src/test/java/org/mapdb/Issue254Test.java +++ /dev/null @@ -1,195 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.File; -import java.util.Collection; -import java.util.Map; - -import static org.junit.Assert.*; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class Issue254Test { - - @Test - public void test(){ - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f) - .transactionDisable() - .make(); - - db.getAtomicLong("long").set(1L); - db.close(); - - db = DBMaker.newFileDB(f) - .transactionDisable() - .readOnly() - .closeOnJvmShutdown() - .make(); - - assertEquals(0L, db.getAtomicLong("non-existing long").get()); - - db.close(); - } - - - DB ro; - - { - File f = UtilsTest.tempDbFile(); - ro = DBMaker.newFileDB(f).transactionDisable().transactionDisable().make(); - ro = DBMaker.newFileDB(f).transactionDisable().transactionDisable().readOnly().make(); - } - - @Test - public void atomic_long(){ - Atomic.Long l = ro.getAtomicLong("non-existing"); - assertEquals(0L, l.get()); - try{ - l.set(1); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - @Test - public void atomic_int(){ - Atomic.Integer l = ro.getAtomicInteger("non-existing"); - assertEquals(0, l.get()); - try{ - l.set(1); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - @Test - public void atomic_boolean(){ - Atomic.Boolean l = ro.getAtomicBoolean("non-existing"); - assertEquals(false, l.get()); - try{ - l.set(true); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - @Test - public void atomic_string(){ - Atomic.String l = ro.getAtomicString("non-existing"); - assertEquals("", l.get()); - try{ - l.set("a"); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - @Test - public void atomic_var(){ - Atomic.Var l = ro.getAtomicVar("non-existing"); - assertEquals(null, l.get()); - try{ - l.set("a"); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - @Test - public void atomic_queue(){ - Collection l = ro.getQueue("non-existing"); - assertTrue(l.isEmpty()); - try{ - l.add("a"); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - @Test - public void atomic_stack(){ - Collection l = ro.getStack("non-existing"); - assertTrue(l.isEmpty()); - try{ - l.add("a"); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - @Test - public void atomic_circular_queue(){ - Collection l = ro.getCircularQueue("non-existing"); - assertTrue(l.isEmpty()); - try{ - l.add("a"); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - - @Test - public void atomic_tree_set(){ - Collection l = ro.getTreeSet("non-existing"); - assertTrue(l.isEmpty()); - try{ - l.add("a"); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - @Test - public void atomic_hash_set(){ - Collection l = ro.getHashSet("non-existing"); - assertTrue(l.isEmpty()); - try{ - l.add("a"); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - - @Test - public void atomic_tree_map(){ - Map l = ro.getTreeMap("non-existing"); - assertTrue(l.isEmpty()); - try{ - l.put("a", "a"); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - @Test - public void atomic_hash_map(){ - Map l = ro.getHashMap("non-existing"); - assertTrue(l.isEmpty()); - try{ - l.put("a","a"); - fail(); - }catch(UnsupportedOperationException e){ - assertEquals("Read-only",e.getMessage()); - } - } - - - - - - -} diff --git a/src/test/java/org/mapdb/Issue258Test.java b/src/test/java/org/mapdb/Issue258Test.java deleted file mode 100644 index 58ffe745b..000000000 --- a/src/test/java/org/mapdb/Issue258Test.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.util.concurrent.BlockingQueue; - -public class Issue258Test { - - - @Test - public void test() throws IOException { - - File tmp = File.createTempFile("mapdb",""); - - - for(int i=0;i<10;i++){ - DB db = DBMaker.newFileDB(tmp) - .mmapFileEnable() -// .closeOnJvmShutdown() -// .compressionEnable() -// .cacheLRUEnable() -// .asyncWriteEnable() - .make(); - - BlockingQueue map = db.getStack("undolog"); - - for(int j=0; !map.isEmpty() && j < 100; j++) - { - Object obj = map.poll(); - - } - map.clear(); - - for (int k=0; k < 100000; k++) - { - - String cmd = "iasdkaokdas"+i; - map.add(cmd); - } - - db.commit(); - db.close(); - } - - } -} diff --git a/src/test/java/org/mapdb/Issue265Test.java b/src/test/java/org/mapdb/Issue265Test.java deleted file mode 100644 index 7820cab37..000000000 --- a/src/test/java/org/mapdb/Issue265Test.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.mapdb; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.Map; - -public class Issue265Test { - - @Test - public void compact(){ - DBMaker dbMaker = DBMaker.newMemoryDB() - .transactionDisable() // breaks functionality even in version 0.9.7 - .cacheDisable(); - DB db = dbMaker.make(); - try { - Map map = db.getHashMap("HashMap"); - map.put(1, "one"); - map.put(2, "two"); - map.remove(1); - db.commit(); - db.compact(); - Assert.assertEquals(1, map.size()); - } finally { - db.close(); - } - } - - @Test - public void compact_no_tx(){ - DBMaker dbMaker = DBMaker.newMemoryDB() - .cacheDisable(); - DB db = dbMaker.make(); - try { - Map map = db.getHashMap("HashMap"); - map.put(1, "one"); - map.put(2, "two"); - map.remove(1); - db.commit(); - db.compact(); - Assert.assertEquals(1, map.size()); - } finally { - db.close(); - } - } - -} diff --git a/src/test/java/org/mapdb/Issue266Test.java b/src/test/java/org/mapdb/Issue266Test.java deleted file mode 100644 index 2fb70e4e1..000000000 --- a/src/test/java/org/mapdb/Issue266Test.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.mapdb; - -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.util.Set; - -import static org.junit.Assert.assertEquals; - -enum AdvancedEnum { - A() { - @Override - public void dummy() { - System.out.println("dummy1"); - } - }, - B() { - @Override - public void dummy() { - System.out.println("dummy2"); - } - }, - C() { - @Override - public void dummy() { - System.out.println("dummy3"); - } - }; - - public abstract void dummy(); - - - -} - - -public class Issue266Test { - @Test - public void testEnum() throws IOException { - - File f = File.createTempFile("mapdb","asdas"); - DB db = DBMaker.newFileDB(f).make(); - - AdvancedEnum testEnumValue = AdvancedEnum.C; - - Set set = db.createTreeSet("set").makeOrGet(); - set.clear(); - - set.add(testEnumValue); - db.commit(); - - db.close(); - - db = DBMaker.newFileDB(f).make(); - - set = db.createTreeSet("set").makeOrGet(); - AdvancedEnum enumValue = (AdvancedEnum)set.iterator().next(); - - Assert.assertNotNull(enumValue); - - assertEquals("Invalid Enum.name()", enumValue.name(), testEnumValue.name()); - assertEquals("Invalid Enum.ordinal()", enumValue.ordinal(), testEnumValue.ordinal()); - } - - @Test public void testEnum2(){ - assertEquals(AdvancedEnum.A, AdvancedEnum.class.getEnumConstants()[0]); - - - DB db = DBMaker.newMemoryDB().make(); - AdvancedEnum a = (AdvancedEnum) UtilsTest.clone(AdvancedEnum.A, db.getDefaultSerializer()); - assertEquals(a.toString(),AdvancedEnum.A.toString()); - assertEquals(a.ordinal(),AdvancedEnum.A.ordinal()); - - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/Issue308Test.java b/src/test/java/org/mapdb/Issue308Test.java deleted file mode 100644 index cd3106e95..000000000 --- a/src/test/java/org/mapdb/Issue308Test.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.Iterator; -import java.util.concurrent.atomic.AtomicLong; - -public class Issue308Test { - - @Test - public void test() { - DB db = DBMaker.newTempFileDB() - .mmapFileEnableIfSupported() - .compressionEnable() - .transactionDisable() - .checksumEnable() - .commitFileSyncDisable() - .make(); - Iterator> newIterator = new Iterator>() { - private AtomicLong value = new AtomicLong(10000000); - - @Override - public boolean hasNext() { - return value.get() > 0; - } - - @Override - public Fun.Pair next() { - Long v = value.decrementAndGet(); - return new Fun.Pair(v, v.toString()); - } - - @Override - public void remove() { - - } - }; - BTreeMap cubeData = db.createTreeMap("data").pumpSource(newIterator).make(); - } -} diff --git a/src/test/java/org/mapdb/Issue312Test.java b/src/test/java/org/mapdb/Issue312Test.java deleted file mode 100644 index ec20996e3..000000000 --- a/src/test/java/org/mapdb/Issue312Test.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.util.Map; - -public class Issue312Test { - - @Test - public void test() throws IOException{ - File f = File.createTempFile("mapdb","test"); - DB db = DBMaker.newFileDB(f) - .mmapFileEnableIfSupported() - .transactionDisable() - .make(); - - Map map = db.createTreeMap("data").make(); - for(long i = 0; i<100000;i++){ - map.put(i,i + "hi my friend " + i); - } - db.commit(); - db.close(); - - db = DBMaker.newFileDB(f) - .mmapFileEnableIfSupported() - .transactionDisable() - .readOnly() - .make(); - - - } -} diff --git a/src/test/java/org/mapdb/Issue321Test.java b/src/test/java/org/mapdb/Issue321Test.java deleted file mode 100644 index 6615ffdea..000000000 --- a/src/test/java/org/mapdb/Issue321Test.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -public class Issue321Test { - - @Test - public void npe(){ - - DB db = DBMaker.newMemoryDB().make(); - - List l = Arrays.asList(19,10,9,8,2); - - Map m = db.createTreeMap("aa") - .pumpPresort(100) - .make(); - - } -} diff --git a/src/test/java/org/mapdb/Issue332Test.java b/src/test/java/org/mapdb/Issue332Test.java deleted file mode 100644 index b14989521..000000000 --- a/src/test/java/org/mapdb/Issue332Test.java +++ /dev/null @@ -1,110 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.*; -import java.util.Map; - -import static org.junit.Assert.assertEquals; - -/** - * Created by paspi on 26.05.2014. - */ -public class Issue332Test { - - // 4 length bytes will be prepended to this string: 000000ef - final static String problem = "76fa135e7d216e829a53845a983469ac1e4edb6120b79667d667e7d4f8560101010100000022bf456901000000230000002102123eeaa90e2f5786ce028e60ec03702706dadecee373a90b09b88a99cc668f46ac3358c8ea6433279c678846fb6e06eeccd82e2fe888f2ac203476d3918cd405790100000038ffffff9e000000be438253be43825301000000109bf45901000000230000002102123eeaa90e2f5786ce028e60ec03702706dadecee373a90b09b88a99cc668f46ac38bf80f10129594a7e949cc43c3bd6f8670ba5ab59874305f6839406738a9cf90100000038ffffff9e00000081bd175381bd1753"; - public static final Serializer.CompressionWrapper VALUE_SERIALIZER = new Serializer.CompressionWrapper(new TestSerializer()); - - public static final class TestSerializer implements Serializer, Serializable { - - // http://stackoverflow.com/a/140430 - private static byte[] fromHexString(final String encoded) { - if ((encoded.length() % 2) != 0) - throw new IllegalArgumentException("Input string must contain an even number of characters"); - - final byte result[] = new byte[encoded.length()/2]; - final char enc[] = encoded.toCharArray(); - for (int i = 0; i < enc.length; i += 2) { - StringBuilder curr = new StringBuilder(2); - curr.append(enc[i]).append(enc[i + 1]); - result[i/2] = (byte) Integer.parseInt(curr.toString(), 16); - } - return result; - } - - // http://stackoverflow.com/a/13006907 - private static String bytArrayToHex(byte[] a) { - StringBuilder sb = new StringBuilder(); - for(byte b: a) - sb.append(String.format("%02x", b&0xff)); - return sb.toString(); - } - - - @Override - public void serialize(DataOutput out, String value) throws IOException { - byte [] buf = fromHexString(value); - out.writeInt(buf.length); - out.write(buf); - } - - @Override - public String deserialize(DataInput in, int available) throws IOException { - int nsize = in.readInt(); - byte[] buf = new byte[nsize]; - in.readFully(buf); - - return bytArrayToHex(buf); - } - - @Override - public int fixedSize() { - return -1; - } - } - - @Test - public void run() throws IOException { - File f = File.createTempFile("mapdb","mapdb"); - DB db = DBMaker.newFileDB(f) - .closeOnJvmShutdown() - .make(); - - Map testMap = db.createHashMap("testmap") - .valueSerializer(VALUE_SERIALIZER) - //.valueSerializer(new TestSerializer()) - .makeOrGet(); - - testMap.put(1, problem); - db.commit(); - db.close(); - - db = null; - testMap = null; - - //------------------------- - db = DBMaker.newFileDB(f) - .closeOnJvmShutdown() - .make(); - testMap = db.createHashMap("testmap") - .valueSerializer(VALUE_SERIALIZER) - .makeOrGet(); - String deserialized = testMap.get(1); - - db.close(); - assertEquals(problem,deserialized); - } - - @Test public void test_ser_itself(){ - String other = UtilsTest.clone(problem, new TestSerializer()); - assertEquals(problem, other); - } - - @Test public void test_comp(){ - String other = UtilsTest.clone(problem, VALUE_SERIALIZER); - assertEquals(problem, other); - } - - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/Issue353Test.java b/src/test/java/org/mapdb/Issue353Test.java deleted file mode 100644 index 59f5f8537..000000000 --- a/src/test/java/org/mapdb/Issue353Test.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.mapdb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.io.File; -import java.util.Random; -import java.util.concurrent.ConcurrentMap; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mapdb.DB; -import org.mapdb.DB.HTreeMapMaker; -import org.mapdb.DBMaker; -import org.mapdb.Hasher; -import org.mapdb.Serializer; - -public class Issue353Test { - - private ConcurrentMap map; - private DB db; - private Random random = new Random(); - private static final int ITERATIONS = 40000; - - @Before - public void setupDb() { - db = DBMaker.newFileDB(UtilsTest.tempDbFile()).closeOnJvmShutdown().mmapFileEnableIfSupported() - .commitFileSyncDisable().transactionDisable().compressionEnable().freeSpaceReclaimQ(0).make(); - HTreeMapMaker maker = db.createHashMap("products").hasher(Hasher.BYTE_ARRAY) - .valueSerializer(Serializer.BYTE_ARRAY).keySerializer(Serializer.BYTE_ARRAY).counterEnable(); - map = maker.makeOrGet(); - } - - @After - public void shutdownDb() { - db.close(); - } - - @Test - public void iterateKeySet() { - db.commit(); - map.clear(); - db.commit(); - for (int i = 0; i < ITERATIONS; i++) { - map.put(createByteArrayForKey(), createByteArrayForValue()); - } - for (byte[] e : map.keySet()) { - assertNotNull(map.get(e)); - } - assertEquals(ITERATIONS, map.size()); - map.clear(); - db.commit(); - assertEquals(0, map.size()); - for (byte[] e : map.keySet()) { - fail(); - } - map.put(createByteArrayForKey(), createByteArrayForValue()); - db.commit(); - assertEquals(1, map.size()); - boolean found = false; - for (byte[] e : map.keySet()) { - if (found == true) { - fail(); - } - found = true; - } - } - - private byte[] createByteArrayForKey() { - byte[] result = new byte[12]; - random.nextBytes(result); - return result; - } - - private byte[] createByteArrayForValue() { - int size = random.nextInt(300) + 200; - byte[] result = new byte[size]; - random.nextBytes(result); - return result; - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/Issue37Test.java b/src/test/java/org/mapdb/Issue37Test.java deleted file mode 100644 index 5a0aa1f34..000000000 --- a/src/test/java/org/mapdb/Issue37Test.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; - -import static junit.framework.TestCase.assertEquals; -import static org.junit.Assert.assertTrue; - -public class Issue37Test { - - - - @Test public void test3(){ - - DB db = DBMaker.newMemoryDirectDB().transactionDisable().asyncWriteFlushDelay(100).make(); - ConcurrentMap orders = db.createHashMap("order").make(); - for(int i = 0; i < 10000; i++) { - orders.put((long)i, (long)i); - } - assertEquals(10000, orders.size()); - - - int progress = 0; - Set returned = new LinkedHashSet(); - Iterator iter = orders.keySet().iterator(); - while(iter.hasNext()) { - Object key = iter.next(); - - if(returned.contains(key)) - throw new AssertionError("already found: "+key); - returned.add(key); - progress++; - assertTrue(progress <= 10000); - } - - iter = orders.entrySet().iterator(); - progress=0; - while(iter.hasNext()) { - progress++; - iter.next(); - assertTrue(progress <= 10000); - } - - iter = orders.values().iterator(); - progress=0; - while(iter.hasNext()) { - progress++; - iter.next(); - assertTrue(progress <= 10000); - } - - } - -} diff --git a/src/test/java/org/mapdb/Issue41Test.java b/src/test/java/org/mapdb/Issue41Test.java deleted file mode 100644 index f9159e7a8..000000000 --- a/src/test/java/org/mapdb/Issue41Test.java +++ /dev/null @@ -1,286 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.*; -import java.util.Iterator; -import java.util.UUID; -import java.util.concurrent.*; - -/** - * https://github.com/jankotek/MapDB/issues/41 - * @author Laurent Pellegrino - * - * TODO fully investigate this concurrent issue. - */ -public class Issue41Test { - - private static int NB_OPERATIONS = 1000; - - private File DB_PATH = UtilsTest.tempDbFile(); - - private static String MAP_NAME = "mymap"; - - private DB db; - - private HTreeMap map; - - private ExecutorService threadPool; - - private CountDownLatch doneSignal; - - @Before - public void setUp() { - db = - DBMaker.newFileDB(DB_PATH) - .cacheSoftRefEnable() - .closeOnJvmShutdown() - .deleteFilesAfterClose() - .transactionDisable() - .make(); - - map = - db.createHashMap(MAP_NAME) - .keySerializer(new Key.Serializer()) - .valueSerializer(new Value.Serializer()) - .make(); - - threadPool = Executors.newFixedThreadPool(16); - - doneSignal = new CountDownLatch(NB_OPERATIONS); - - - } - - @Test - public void test1() throws InterruptedException { - final Value value = new Value(); - final Key key = new Key(value, "http://www.mapdb.org/"); - - for (int i = 0; i < NB_OPERATIONS; i++) { - final int j = i; - - threadPool.execute(new Runnable() { - - @Override - public void run() { - try { - map.put(key, value); - } finally { - doneSignal.countDown(); -// System.out.println("OP " + j); - } - } - }); - } - } - - @Test - public void test2() throws InterruptedException { - final ConcurrentMap alreadyAdded = - new ConcurrentHashMap(); - - for (int i = 0; i < NB_OPERATIONS; i++) { - final int j = i; - - threadPool.execute(new Runnable() { - - @Override - public void run() { - try { - if (j % 2 == 0) { - Value value = new Value(); - Key key = new Key(value, Integer.toString(j)); - - alreadyAdded.putIfAbsent(key, value); - map.putIfAbsent(key, value); - } else { - Iterator it = alreadyAdded.keySet().iterator(); - - if (it.hasNext()) { - map.get(it.next()); - } - } - } finally { - doneSignal.countDown(); -// System.out.println("OP " + j); - } - } - }); - } - } - - @After - public void tearDown() throws InterruptedException { - doneSignal.await(); - threadPool.shutdown(); - db.close(); - } - - public static class Value implements Serializable { - - private static final long serialVersionUID = 1L; - - public static final Serializer SERIALIZER = new Serializer(); - - protected final UUID value; - - public Value() { - this.value = UUID.randomUUID(); - } - - private Value(UUID uuid) { - this.value = uuid; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.value == null) - ? 0 : this.value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Value)) { - return false; - } - Value other = (Value) obj; - if (this.value == null) { - if (other.value != null) { - return false; - } - } else if (!this.value.equals(other.value)) { - return false; - } - return true; - } - - public static final class Serializer implements - org.mapdb.Serializer, Serializable { - - private static final long serialVersionUID = 140L; - - @Override - public void serialize(DataOutput out, Value value) - throws IOException { - out.writeLong(value.value.getMostSignificantBits()); - out.writeLong(value.value.getLeastSignificantBits()); - } - - @Override - public Value deserialize(DataInput in, int available) - throws IOException { - return new Value(new UUID(in.readLong(), in.readLong())); - } - - @Override - public int fixedSize() { - return -1; - } - - - } - - } - - public static class Key implements Serializable { - - private static final long serialVersionUID = 1L; - - protected final Value subscriptionId; - - protected final String eventId; - - public Key(Value subscriptionId, String eventId) { - this.subscriptionId = subscriptionId; - this.eventId = eventId; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.eventId == null) - ? 0 : this.eventId.hashCode()); - result = prime * result + ((this.subscriptionId == null) - ? 0 : this.subscriptionId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Key)) { - return false; - } - Key other = (Key) obj; - if (this.eventId == null) { - if (other.eventId != null) { - return false; - } - } else if (!this.eventId.equals(other.eventId)) { - return false; - } - if (this.subscriptionId == null) { - if (other.subscriptionId != null) { - return false; - } - } else if (!this.subscriptionId.equals(other.subscriptionId)) { - return false; - } - return true; - } - - public static final class Serializer implements - org.mapdb.Serializer, Serializable { - - private static final long serialVersionUID = 1L; - - @Override - public void serialize(DataOutput out, Key notificationId) - throws IOException { - out.writeUTF(notificationId.eventId); - - Value.SERIALIZER.serialize(out, notificationId.subscriptionId); - } - - @Override - public Key deserialize(DataInput in, int available) - throws IOException { - String eventId = in.readUTF(); - - Value subscriptionId = - Value.SERIALIZER.deserialize(in, available); - - return new Key(subscriptionId, eventId); - } - - - @Override - public int fixedSize() { - return -1; - } - - } - - } - - - -} diff --git a/src/test/java/org/mapdb/Issue69Test.java b/src/test/java/org/mapdb/Issue69Test.java deleted file mode 100644 index be18b1a80..000000000 --- a/src/test/java/org/mapdb/Issue69Test.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.util.Map; - -import static org.junit.Assert.fail; - -/** - * https://github.com/jankotek/MapDB/issues/69 - * - * @author Konstantin Zadorozhny - * - */ -public class Issue69Test { - - private DB db; - - @Before - public void setUp() { - db = DBMaker.newTempFileDB() - .transactionDisable() - .checksumEnable() - .deleteFilesAfterClose() - .make(); - } - - @After - public void tearDown() throws InterruptedException { - db.close(); - } - - @Test - public void testStackOverflowError() throws Exception { - - try{ - Map map = db.getHashMap("test"); - - StringBuilder buff = new StringBuilder(); - - long maxIterations = 1000000; - int valueLength = 1024; - long maxKeys = 1000; - long i = 1; - while (i < maxIterations) { - - if (i % 10000 == 0) { - valueLength ++; -// System.out.println("Iteration: " + i + "; Value length: " + valueLength); - } - - String key = "key" + (int)(Math.random() * maxKeys); - buff.setLength(valueLength); - map.put(key, buff.toString()); - - i++; - - } - }catch(Throwable e){ - while(e!=null){ - for(StackTraceElement ee: e.getStackTrace()){ - System.out.println(ee); - } - System.out.println(); - e = e.getCause(); - } - fail(); - } - - - } - - -} diff --git a/src/test/java/org/mapdb/Issue77Test.java b/src/test/java/org/mapdb/Issue77Test.java deleted file mode 100644 index a00b0c03e..000000000 --- a/src/test/java/org/mapdb/Issue77Test.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.mapdb; - - -import org.junit.After; -import org.junit.Test; - -import java.io.File; -import java.util.Random; -import java.util.concurrent.ConcurrentNavigableMap; - -public class Issue77Test { - private Random random = new Random(1); - private File dir = new File(UtilsTest.tempDbFile()+"aaa"); - - @Test - public void run(){ - create(); - read(); // UnsupportedOperationException - read(); // InternalError - } - - DB open(boolean readOnly) { - // This works: - // DBMaker maker = DBMaker.newFileDB(new File(dir + "/test")); - // This is faster, but fails if read() is called for the second time: - DBMaker maker = DBMaker.newAppendFileDB(new File(dir + "/test")); - if (readOnly) { - maker.readOnly(); - } -// maker.randomAccessFileEnableIfNeeded(); - maker.closeOnJvmShutdown(); - DB db = maker.make(); // InternalError, UnsupportedOperationException - return db; - } - - void create() { - dir.mkdirs(); - DB db = open(false); - ConcurrentNavigableMap map = db.getTreeMap("bytes"); - int n = 10; - int m = 10; - for (int i = 0; i < n; i++) { - map.put(i, getRandomData(m)); - } - db.commit(); - db.close(); - } - - void read() { - DB db = open(true); // InternalError, UnsupportedOperationException - db.close(); - } - - byte[] getRandomData(int n) { - byte[] c = new byte[n]; - random.nextBytes(c); - return c; - } - - @After - public void cleanup(){ - for (File f : dir.listFiles()) { - f.delete(); - } - - } -} diff --git a/src/test/java/org/mapdb/Issue78Test.java b/src/test/java/org/mapdb/Issue78Test.java deleted file mode 100644 index c2ef8139e..000000000 --- a/src/test/java/org/mapdb/Issue78Test.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOError; - -/** - * https://github.com/jankotek/MapDB/issues/78 - * - * @author Nandor Kracser - */ -public class Issue78Test { - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } - - @Test(expected = IOError.class, timeout = 10000) - public void testIssue() { - DB db = DBMaker.newTempFileDB().make(); - HTreeMap usersMap = db.getHashMap("values"); - usersMap.put("thisKillsTheAsyncWriteThread", new NotSerializable()); - db.commit(); - } - - class NotSerializable { - } -} diff --git a/src/test/java/org/mapdb/Issue86Test.java b/src/test/java/org/mapdb/Issue86Test.java deleted file mode 100644 index df85a1da2..000000000 --- a/src/test/java/org/mapdb/Issue86Test.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.Serializable; -import java.util.Map; - -/** - * - * @author M.Y. Developers - */ -public class Issue86Test { - public static DB createFileStore() { - return DBMaker - .newTempFileDB() - .transactionDisable() - .make(); - } - - @Test - public void Array() { - DB createFileStore = createFileStore(); - Map map = createFileStore.getTreeMap("testMap"); - int maxSize = 1000; - for (int i = 1; i < maxSize; i++) { - String[] array = new String[i]; - for (int j = 0; j < i; j++) { - array[j] = UtilsTest.randomString(100); - } - map.put(i, array); - } - } - - @Test - public void FieldArray() { - DB createFileStore = createFileStore(); - Map map = createFileStore.getTreeMap("testMap"); - int maxSize = 1000; - for (int i = 1; i < maxSize; i++) { - map.put(i, new StringContainer(i)); - } - } - - private static class StringContainer implements Serializable { - - public String[] container; - - public StringContainer() { - } - - public String[] getContainer() { - return container; - } - - public void setContainer(String[] container) { - this.container = container; - } - - public StringContainer(int size) { - container = new String[size]; - for (int i = 0; i < size; i++) { - container[i] = UtilsTest.randomString(100); - } - } - } -} diff --git a/src/test/java/org/mapdb/Issue89Test.java b/src/test/java/org/mapdb/Issue89Test.java deleted file mode 100644 index a52a37ca2..000000000 --- a/src/test/java/org/mapdb/Issue89Test.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.mapdb; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.File; -import java.util.NavigableSet; - -public class Issue89Test { - - - private static final String MY_TEST_DATA_FILE = UtilsTest.tempDbFile().getAbsolutePath(); - private static final String MAP_DB_DATA_FILE_TO_REMOVE = MY_TEST_DATA_FILE + ".0"; - private static final String TEST_TREE_SET = "TestTreeSet"; - private static final String DUMMY_CONTENT = "DummyContent"; - - - @Before - public void setUp() throws Exception { - deleteFile(); - } - - @After - public void tearDown() throws Exception { - deleteFile(); - } - - - @Test - public void testAppend() throws Exception { - appendToDataFile(); - appendToDataFile(); - appendToDataFile(); - appendToDataFile(); - } - - - private void appendToDataFile() { - final DB myTestDataFile = createMapDB(MY_TEST_DATA_FILE); - addData(myTestDataFile); - myTestDataFile.close(); - } - - - private void addData(DB myTestDataFile) { - final NavigableSet testTreeSet = myTestDataFile.getTreeSet(TEST_TREE_SET); - testTreeSet.add(DUMMY_CONTENT); - myTestDataFile.commit(); - - } - - - private DB createMapDB(String fileName) { - final File file = new File(fileName); - return createMapDB(file); - } - - - private DB createMapDB(File file) { - return DBMaker.newAppendFileDB(file) - .closeOnJvmShutdown() - .cacheDisable() - .make(); - } - - - private void deleteFile() { - final File file = new File(MAP_DB_DATA_FILE_TO_REMOVE); - if (file.exists()) { - file.delete(); - } - } - - - } diff --git a/src/test/java/org/mapdb/Issue90Test.java b/src/test/java/org/mapdb/Issue90Test.java deleted file mode 100644 index 205fbe1d7..000000000 --- a/src/test/java/org/mapdb/Issue90Test.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.File; - -public class Issue90Test { - - @Test - public void testCounter() throws Exception { - File file = UtilsTest.tempDbFile(); - - - final DB mapDb =DBMaker.newAppendFileDB(file) - .closeOnJvmShutdown() - .compressionEnable() //This is the cause of the exception. If compression is not used, no exception occurs. - - .cacheDisable() - .make(); - final Atomic.Long myCounter = mapDb.getAtomicLong("MyCounter"); - - final BTreeMap> treeMap = mapDb.getTreeMap("map"); - Bind.size(treeMap, myCounter); - - for (int i = 0; i < 3; i++) { - treeMap.put("key_" + i, new Fun.Pair("value_", i)); - } - } - - - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/IssuesTest.java b/src/test/java/org/mapdb/IssuesTest.java deleted file mode 100644 index 120a6e60b..000000000 --- a/src/test/java/org/mapdb/IssuesTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.Map; - -public class IssuesTest { - - @Test public void issue130(){ - DB db = DBMaker.newAppendFileDB(UtilsTest.tempDbFile()) - .closeOnJvmShutdown() - .make(); - - Map store = db.getTreeMap("collectionName"); - - - } -} diff --git a/src/test/java/org/mapdb/JSR166TestCase.java b/src/test/java/org/mapdb/JSR166TestCase.java deleted file mode 100644 index f95bbce28..000000000 --- a/src/test/java/org/mapdb/JSR166TestCase.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.mapdb; - -import junit.framework.TestCase; - -abstract public class JSR166TestCase extends TestCase { - - /** - * The number of elements to place in collections, arrays, etc. - */ - public static final int SIZE = 20; - - - - public static final Integer zero = new Integer(0); - public static final Integer one = new Integer(1); - public static final Integer two = new Integer(2); - public static final Integer three = new Integer(3); - public static final Integer four = new Integer(4); - public static final Integer five = new Integer(5); - public static final Integer six = new Integer(6); - public static final Integer seven = new Integer(7); - public static final Integer eight = new Integer(8); - public static final Integer nine = new Integer(9); - public static final Integer m1 = new Integer(-1); - public static final Integer m2 = new Integer(-2); - public static final Integer m3 = new Integer(-3); - public static final Integer m4 = new Integer(-4); - public static final Integer m5 = new Integer(-5); - public static final Integer m6 = new Integer(-6); - public static final Integer m10 = new Integer(-10); - - /** - * Fails with message "should throw exception". - */ - public void shouldThrow() { - fail("Should throw exception"); - } - - -} diff --git a/src/test/java/org/mapdb/LongConcurrentHashMapTest.java b/src/test/java/org/mapdb/LongConcurrentHashMapTest.java deleted file mode 100644 index 399cf7069..000000000 --- a/src/test/java/org/mapdb/LongConcurrentHashMapTest.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - * Other contributors include Andrew Wright, Jeffrey Hayes, - * Pat Fisher, Mike Judd. - */ - -package org.mapdb; - -import junit.framework.TestCase; - -import java.util.Iterator; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class LongConcurrentHashMapTest extends TestCase{ - - /** - * Create a map from Integers 1-5 to Strings "A"-"E". - */ - private static LongConcurrentHashMap map5() { - LongConcurrentHashMap map = new LongConcurrentHashMap(5); - assertTrue(map.isEmpty()); - map.put(1, "A"); - map.put(2, "B"); - map.put(3, "C"); - map.put(4, "D"); - map.put(5, "E"); - assertFalse(map.isEmpty()); - assertEquals(5, map.size()); - return map; - } - - /** - * clear removes all pairs - */ - public void testClear() { - LongConcurrentHashMap map = map5(); - map.clear(); - assertEquals(map.size(), 0); - } - - - - /** - * containsKey returns true for contained key - */ - public void testContainsKey() { - LongConcurrentHashMap map = map5(); - assertTrue(map.containsKey(1)); - assertFalse(map.containsKey(0)); - } - - /** - * containsValue returns true for held values - */ - public void testContainsValue() { - LongConcurrentHashMap map = map5(); - assertTrue(map.containsValue("A")); - assertFalse(map.containsValue("Z")); - } - - /** - * enumeration returns an enumeration containing the correct - * elements - */ - public void testEnumeration() { - LongConcurrentHashMap map = map5(); - Iterator e = map.valuesIterator(); - int count = 0; - while(e.hasNext()){ - count++; - e.next(); - } - assertEquals(5, count); - } - - /** - * get returns the correct element at the given key, - * or null if not present - */ - public void testGet() { - LongConcurrentHashMap map = map5(); - assertEquals("A", (String)map.get(1)); - assertNull(map.get(-1)); - } - - /** - * isEmpty is true of empty map and false for non-empty - */ - public void testIsEmpty() { - LongConcurrentHashMap empty = new LongConcurrentHashMap(); - LongConcurrentHashMap map = map5(); - assertTrue(empty.isEmpty()); - assertFalse(map.isEmpty()); - } - - - - - /** - * putIfAbsent works when the given key is not present - */ - public void testPutIfAbsent() { - LongConcurrentHashMap map = map5(); - map.putIfAbsent(6, "Z"); - assertTrue(map.containsKey(6)); - } - - /** - * putIfAbsent does not add the pair if the key is already present - */ - public void testPutIfAbsent2() { - LongConcurrentHashMap map = map5(); - assertEquals("A", map.putIfAbsent(1, "Z")); - } - - /** - * replace fails when the given key is not present - */ - public void testReplace() { - LongConcurrentHashMap map = map5(); - assertNull(map.replace(6, "Z")); - assertFalse(map.containsKey(6)); - } - - /** - * replace succeeds if the key is already present - */ - public void testReplace2() { - LongConcurrentHashMap map = map5(); - assertNotNull(map.replace(1, "Z")); - assertEquals("Z", map.get(1)); - } - - - /** - * replace value fails when the given key not mapped to expected value - */ - public void testReplaceValue() { - LongConcurrentHashMap map = map5(); - assertEquals("A", map.get(1)); - assertFalse(map.replace(1, "Z", "Z")); - assertEquals("A", map.get(1)); - } - - /** - * replace value succeeds when the given key mapped to expected value - */ - public void testReplaceValue2() { - LongConcurrentHashMap map = map5(); - assertEquals("A", map.get(1)); - assertTrue(map.replace(1, "A", "Z")); - assertEquals("Z", map.get(1)); - } - - - /** - * remove removes the correct key-value pair from the map - */ - public void testRemove() { - LongConcurrentHashMap map = map5(); - map.remove(5); - assertEquals(4, map.size()); - assertFalse(map.containsKey(5)); - } - - /** - * remove(key,value) removes only if pair present - */ - public void testRemove2() { - LongConcurrentHashMap map = map5(); - map.remove(5, "E"); - assertEquals(4, map.size()); - assertFalse(map.containsKey(5)); - map.remove(4, "A"); - assertEquals(4, map.size()); - assertTrue(map.containsKey(4)); - - } - - /** - * size returns the correct values - */ - public void testSize() { - LongConcurrentHashMap map = map5(); - LongConcurrentHashMap empty = new LongConcurrentHashMap(); - assertEquals(0, empty.size()); - assertEquals(5, map.size()); - } - - - // Exception tests - - /** - * Cannot create with negative capacity - */ - public void testConstructor1() { - try { - new LongConcurrentHashMap(-1,0,1); - shouldThrow(); - } catch(IllegalArgumentException e){} - } - - /** - * Cannot create with negative concurrency level - */ - public void testConstructor2() { - try { - new LongConcurrentHashMap(1,0,-1); - shouldThrow(); - } catch(IllegalArgumentException e){} - } - - /** - * Cannot create with only negative capacity - */ - public void testConstructor3() { - try { - new LongConcurrentHashMap(-1); - shouldThrow(); - } catch(IllegalArgumentException e){} - } - - - - /** - * containsValue(null) throws NPE - */ - public void testContainsValue_NullPointerException() { - try { - LongConcurrentHashMap c = new LongConcurrentHashMap(5); - c.containsValue(null); - shouldThrow(); - } catch(NullPointerException e){} - } - - - - /** - * fail with message "should throw exception" - */ - public void shouldThrow() { - fail("Should throw exception"); - } - -} diff --git a/src/test/java/org/mapdb/LongConcurrentLRUMapTest.java b/src/test/java/org/mapdb/LongConcurrentLRUMapTest.java deleted file mode 100644 index 478bb8326..000000000 --- a/src/test/java/org/mapdb/LongConcurrentLRUMapTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import static org.junit.Assert.assertTrue; - -public class LongConcurrentLRUMapTest { - - - @Test - public void overfill(){ - final LongConcurrentLRUMap l = new LongConcurrentLRUMap(1000,1000-1); - - for(Long i=0L;i<1e5;i++) { - l.put(i, i); - if(i>0){ - Long other = l.get(i-1); - assertTrue(other==null || (i-1==other)); - } - } - } -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/LongHashMapTest.java b/src/test/java/org/mapdb/LongHashMapTest.java deleted file mode 100644 index 71e03e89f..000000000 --- a/src/test/java/org/mapdb/LongHashMapTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * Copyright 2010 Cees De Groot, Alex Boisvert, Jan Kotek - * - * 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 - * - * http://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. - ******************************************************************************/ -package org.mapdb; - -import junit.framework.TestCase; - -import java.util.Iterator; -import java.util.Random; -import java.util.TreeMap; - -public class LongHashMapTest extends TestCase { - - public void testAll() { - LongHashMap t = new LongHashMap(){ - @Override protected long hashSaltValue(){return 0;} - }; - t.put(1, "aa"); - t.put(2, "bb"); - t.put(2, "bb"); - t.put(4, "cc"); - t.put(9, "FF"); - assertEquals(4, t.size()); - t.remove(1); - assertEquals(3, t.size()); - assertEquals(t.get(1), null); - assertEquals(t.get(2), "bb"); - assertEquals(t.get(3), null); - assertEquals(t.get(4), "cc"); - assertEquals(t.get(5), null); - assertEquals(t.get(-1), null); - assertEquals(t.get(9), "FF"); - - Iterator vals = t.valuesIterator(); - assertTrue(vals.hasNext()); - assertEquals(vals.next(), "bb"); - assertTrue(vals.hasNext()); - assertEquals(vals.next(), "cc"); - assertTrue(vals.hasNext()); - assertEquals(vals.next(), "FF"); - - assertFalse(vals.hasNext()); - - t.clear(); - assertEquals(0, t.size()); - t.put(2, "bb"); - assertEquals(1, t.size()); - assertEquals(t.get(1), null); - assertEquals(t.get(3), null); - - } - - public void testRandomCompare() { - LongHashMap v1 = new LongHashMap(); - TreeMap v2 = new TreeMap(); - Random d = new Random(); - for (int i = 0; i < 1000; i++) { - long key = d.nextInt() % 100; - double random = d.nextDouble(); - if (random < 0.8) { -// System.out.println("put "+key); - v1.put(key, "" + key); - v2.put(key, "" + key); - } else { -// System.out.println("remove "+key); - v1.remove(key); - v2.remove(key); - } - checkEquals(v1, v2); - - } - } - - public void checkEquals(LongMap v1, TreeMap v2) { - assertEquals(v1.size(), v2.size()); - for (long k : v2.keySet()) { - assertEquals(v1.get(k), v2.get(k)); - } - - int counter = 0; - Iterator it = v1.valuesIterator(); - while (it.hasNext()) { - String v = it.next(); - long key = Long.parseLong(v); - assertEquals(v1.get(key), v); - assertEquals("" + key, v); - counter++; - } - assertEquals(counter, v2.size()); - } - - - public void test2() { - LongHashMap v1 = new LongHashMap(); - v1.put(1611, "1611"); - v1.put(15500, "15500"); - v1.put(9446, "9446"); - System.out.println(v1.get(9446)); - System.out.println(v1.toString()); - assertEquals(3, v1.size()); - assertEquals(v1.get(9446), "9446"); - - } - - public void testMapIter(){ - LongHashMap v = new LongHashMap(); - v.put(1L, "one"); - v.put(2L, "two"); - v.put(3L, "three"); - - TreeMap v2 = new TreeMap(); - v2.put(1L, "one"); - v2.put(2L, "two"); - v2.put(3L, "three"); - - TreeMap v3 = new TreeMap(); - LongMap.LongMapIterator iter = v.longMapIterator(); - while(iter.moveToNext()){ - v3.put(iter.key(), iter.value()); - } - - assertEquals(v2,v3); - } - - public void test_Issue6(){ - LongHashMap t = new LongHashMap(); - t.put(6447459, "aa"); - t.put(6382177, "bb"); - assertEquals("aa",t.get(6447459)); - assertEquals("bb",t.get(6382177)); - assertTrue(t.toString().contains("6382177 => bb")); - assertTrue(t.toString().contains("6447459 => aa")); - } - -} diff --git a/src/test/java/org/mapdb/MapInterfaceTest.java b/src/test/java/org/mapdb/MapInterfaceTest.java deleted file mode 100644 index 8e57ab5c5..000000000 --- a/src/test/java/org/mapdb/MapInterfaceTest.java +++ /dev/null @@ -1,1620 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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 - * - * http://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. - */ - -package org.mapdb; - -import junit.framework.TestCase; - -import java.util.*; -import java.util.Map.Entry; - -import static java.util.Collections.singleton; - -/** - * Tests representing the contract of {@link Map}. Concrete subclasses of this - * base class test conformance of concrete {@link Map} subclasses to that - * contract. - *

- * - * @param the type of keys used by the maps under test - * @param the type of mapped values used the maps under test - * @author George van den Driessche - */ -public abstract class MapInterfaceTest extends TestCase { - protected final boolean supportsPut; - protected final boolean supportsRemove; - protected final boolean supportsClear; - protected final boolean allowsNullKeys; - protected final boolean allowsNullValues; - protected final boolean supportsIteratorRemove; - protected final boolean supportsEntrySetValue; - - - /** - * Creates a new, empty instance of the class under test. - * - * @return a new, empty map instance. - * @throws UnsupportedOperationException if it's not possible to make an - * empty instance of the class under test. - */ - protected abstract Map makeEmptyMap() - throws UnsupportedOperationException; - - /** - * Creates a new, non-empty instance of the class under test. - * - * @return a new, non-empty map instance. - * @throws UnsupportedOperationException if it's not possible to make a - * non-empty instance of the class under test. - */ - protected abstract Map makePopulatedMap() - throws UnsupportedOperationException; - - /** - * Creates a new key that is not expected to be found - * in {@link #makePopulatedMap()}. - * - * @return a key. - * @throws UnsupportedOperationException if it's not possible to make a key - * that will not be found in the map. - */ - protected abstract K getKeyNotInPopulatedMap() - throws UnsupportedOperationException; - - /** - * Creates a new value that is not expected to be found - * in {@link #makePopulatedMap()}. - * - * @return a value. - * @throws UnsupportedOperationException if it's not possible to make a value - * that will not be found in the map. - */ - protected abstract V getValueNotInPopulatedMap() - throws UnsupportedOperationException; - - - /** - * Constructor with an explicit {@code supportsIteratorRemove} parameter. - */ - protected MapInterfaceTest( - boolean allowsNullKeys, - boolean allowsNullValues, - boolean supportsPut, - boolean supportsRemove, - boolean supportsClear, - boolean supportsIteratorRemove, - boolean supportsEntrySetValue) { - this.supportsPut = supportsPut; - this.supportsRemove = supportsRemove; - this.supportsClear = supportsClear; - this.allowsNullKeys = allowsNullKeys; - this.allowsNullValues = allowsNullValues; - this.supportsIteratorRemove = supportsIteratorRemove; - this.supportsEntrySetValue = supportsEntrySetValue; - - } - - /** - * Used by tests that require a map, but don't care whether it's - * populated or not. - * - * @return a new map instance. - */ - protected Map makeEitherMap() { - try { - return makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return makeEmptyMap(); - } - } - - protected final boolean supportsValuesHashCode(Map map) { - // get the first non-null value - Collection values = map.values(); - for (V value : values) { - if (value != null) { - try { - value.hashCode(); - } catch (Exception e) { - return false; - } - return true; - } - } - return true; - } - - /** - * Checks all the properties that should always hold of a map. Also calls - * {@link #assertMoreInvariants} to check invariants that are peculiar to - * specific implementations. - * - * @param map the map to check. - * @see #assertMoreInvariants - */ - protected final void assertInvariants(Map map) { - Set keySet = map.keySet(); - Collection valueCollection = map.values(); - Set> entrySet = map.entrySet(); - - assertEquals(map.size() == 0, map.isEmpty()); - assertEquals(map.size(), keySet.size()); - assertEquals(keySet.size() == 0, keySet.isEmpty()); - assertEquals(!keySet.isEmpty(), keySet.iterator().hasNext()); - - int expectedKeySetHash = 0; - for (K key : keySet) { - V value = map.get(key); - expectedKeySetHash += key != null ? key.hashCode() : 0; - assertTrue(map.containsKey(key)); - assertTrue(map.containsValue(value)); - assertTrue(valueCollection.contains(value)); - assertTrue(valueCollection.containsAll(Collections.singleton(value))); - assertTrue(entrySet.contains(mapEntry(key, value))); - assertTrue(allowsNullKeys || (key != null)); - } - assertEquals(expectedKeySetHash, keySet.hashCode()); - - assertEquals(map.size(), valueCollection.size()); - assertEquals(valueCollection.size() == 0, valueCollection.isEmpty()); - assertEquals( - !valueCollection.isEmpty(), valueCollection.iterator().hasNext()); - for (V value : valueCollection) { - assertTrue(map.containsValue(value)); - assertTrue(allowsNullValues || (value != null)); - } - - assertEquals(map.size(), entrySet.size()); - assertEquals(entrySet.size() == 0, entrySet.isEmpty()); - assertEquals(!entrySet.isEmpty(), entrySet.iterator().hasNext()); - assertTrue(!entrySet.contains("foo")); - - boolean supportsValuesHashCode = supportsValuesHashCode(map); - if (supportsValuesHashCode) { - int expectedEntrySetHash = 0; - for (Entry entry : entrySet) { - assertTrue(map.containsKey(entry.getKey())); - assertTrue(entry.toString(), map.containsValue(entry.getValue())); - int expectedHash = - (entry.getKey() == null ? 0 : entry.getKey().hashCode()) ^ - (entry.getValue() == null ? 0 : entry.getValue().hashCode()); - assertEquals(expectedHash, entry.hashCode()); - expectedEntrySetHash += expectedHash; - } - assertEquals(expectedEntrySetHash, entrySet.hashCode()); - assertTrue(entrySet.containsAll(new HashSet>(entrySet))); - assertTrue(entrySet.equals(new HashSet>(entrySet))); - } - - Object[] entrySetToArray1 = entrySet.toArray(); - assertEquals(map.size(), entrySetToArray1.length); - assertTrue(Arrays.asList(entrySetToArray1).containsAll(entrySet)); - - Entry[] entrySetToArray2 = new Entry[map.size() + 2]; - entrySetToArray2[map.size()] = mapEntry("foo", 1); - assertSame(entrySetToArray2, entrySet.toArray(entrySetToArray2)); - assertNull(entrySetToArray2[map.size()]); - assertTrue(Arrays.asList(entrySetToArray2).containsAll(entrySet)); - - Object[] valuesToArray1 = valueCollection.toArray(); - assertEquals(map.size(), valuesToArray1.length); - assertTrue(Arrays.asList(valuesToArray1).containsAll(valueCollection)); - - Object[] valuesToArray2 = new Object[map.size() + 2]; - valuesToArray2[map.size()] = "foo"; - assertSame(valuesToArray2, valueCollection.toArray(valuesToArray2)); - assertNull(valuesToArray2[map.size()]); - assertTrue(Arrays.asList(valuesToArray2).containsAll(valueCollection)); - - if (supportsValuesHashCode) { - int expectedHash = 0; - for (Entry entry : entrySet) { - expectedHash += entry.hashCode(); - } - assertEquals(expectedHash, map.hashCode()); - } - - assertMoreInvariants(map); - } - - /** - * Override this to check invariants which should hold true for a particular - * implementation, but which are not generally applicable to every instance - * of Map. - * - * @param map the map whose additional invariants to check. - */ - protected void assertMoreInvariants(Map map) { - } - - public void testClear() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - if (supportsClear) { - map.clear(); - assertEquals(0, map.size()); - assertTrue(map.isEmpty()); - } else { - try { - map.clear(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testContainsKey() { - final Map map; - final K unmappedKey; - try { - map = makePopulatedMap(); - unmappedKey = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertTrue(!map.containsKey(unmappedKey)); - assertTrue(map.containsKey(map.keySet().iterator().next())); - if (allowsNullKeys) { - map.containsKey(null); - } else { - try { - map.containsKey(null); - } catch (NullPointerException optional) { - } - } - assertInvariants(map); - } - - public void testContainsValue() { - final Map map; - final V unmappedValue; - try { - map = makePopulatedMap(); - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertTrue(!map.containsValue(unmappedValue)); - assertTrue(map.containsValue(map.values().iterator().next())); - if (allowsNullValues) { - map.containsValue(null); - } else { - try { - map.containsKey(null); - } catch (NullPointerException optional) { - } - } - assertInvariants(map); - } - - public void testEntrySet() { - final Map map; - final Set> entrySet; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - entrySet = map.entrySet(); - final K unmappedKey; - final V unmappedValue; - try { - unmappedKey = getKeyNotInPopulatedMap(); - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - for (Entry entry : entrySet) { - assertTrue(!unmappedKey.equals(entry.getKey())); - assertTrue(!unmappedValue.equals(entry.getValue())); - } - } - - public void testEntrySetForEmptyMap() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - } - - public void testEntrySetContainsEntryNullKeyPresent() { - if (!allowsNullKeys || !supportsPut) { - return; - } - final Map map; - final Set> entrySet; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - entrySet = map.entrySet(); - final V unmappedValue; - try { - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - map.put(null, unmappedValue); - Entry entry = mapEntry(null, unmappedValue); - assertTrue(entrySet.contains(entry)); - assertTrue(!entrySet.contains(mapEntry(null, null))); - } - - public void testEntrySetContainsEntryNullKeyMissing() { - final Map map; - final Set> entrySet; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - entrySet = map.entrySet(); - final V unmappedValue; - try { - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - Entry entry = mapEntry(null, unmappedValue); - assertTrue(!entrySet.contains(entry)); - assertTrue(!entrySet.contains(mapEntry(null, null))); - } - - public void testEntrySetIteratorRemove() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Iterator> iterator = entrySet.iterator(); - if (supportsIteratorRemove) { - int initialSize = map.size(); - Entry entry = iterator.next(); - iterator.remove(); - assertEquals(initialSize - 1, map.size()); - assertTrue(!entrySet.contains(entry)); - assertInvariants(map); - try { - iterator.remove(); - fail("Expected IllegalStateException."); - } catch (IllegalStateException e) { - // Expected. - } - } else { - try { - iterator.next(); - iterator.remove(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testEntrySetRemove() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - if (supportsRemove) { - int initialSize = map.size(); - boolean didRemove = entrySet.remove(entrySet.iterator().next()); - assertTrue(didRemove); - assertEquals(initialSize - 1, map.size()); - } else { - try { - entrySet.remove(entrySet.iterator().next()); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testEntrySetRemoveMissingKey() { - final Map map; - final K key; - try { - map = makeEitherMap(); - key = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Entry entry - = mapEntry(key, getValueNotInPopulatedMap()); - int initialSize = map.size(); - if (supportsRemove) { - boolean didRemove = entrySet.remove(entry); - assertTrue(!didRemove); - } else { - try { - boolean didRemove = entrySet.remove(entry); - assertTrue(!didRemove); - } catch (UnsupportedOperationException optional) { - } - } - assertEquals(initialSize, map.size()); - assertTrue(!map.containsKey(key)); - assertInvariants(map); - } - - public void testEntrySetRemoveDifferentValue() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - K key = map.keySet().iterator().next(); - Entry entry - = mapEntry(key, getValueNotInPopulatedMap()); - int initialSize = map.size(); - if (supportsRemove) { - boolean didRemove = entrySet.remove(entry); - assertTrue(!didRemove); - } else { - try { - boolean didRemove = entrySet.remove(entry); - assertTrue(!didRemove); - } catch (UnsupportedOperationException optional) { - } - } - assertEquals(initialSize, map.size()); - assertTrue(map.containsKey(key)); - assertInvariants(map); - } - - public void testEntrySetRemoveNullKeyPresent() { - if (!allowsNullKeys || !supportsPut || !supportsRemove) { - return; - } - final Map map; - final Set> entrySet; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - entrySet = map.entrySet(); - final V unmappedValue; - try { - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - map.put(null, unmappedValue); - assertEquals(unmappedValue, map.get(null)); - assertTrue(map.containsKey(null)); - Entry entry = mapEntry(null, unmappedValue); - assertTrue(entrySet.remove(entry)); - assertNull(map.get(null)); - assertTrue(!map.containsKey(null)); - } - - public void testEntrySetRemoveNullKeyMissing() { - final Map map; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Entry entry - = mapEntry(null, getValueNotInPopulatedMap()); - int initialSize = map.size(); - if (supportsRemove) { - boolean didRemove = entrySet.remove(entry); - assertTrue(!didRemove); - } else { - try { - boolean didRemove = entrySet.remove(entry); - assertTrue(!didRemove); - } catch (UnsupportedOperationException optional) { - } - } - assertEquals(initialSize, map.size()); - assertInvariants(map); - } - - public void testEntrySetRemoveAll() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Set> entriesToRemove = - singleton(entrySet.iterator().next()); - if (supportsRemove) { - int initialSize = map.size(); - boolean didRemove = entrySet.removeAll(entriesToRemove); - assertTrue(didRemove); - assertEquals(initialSize - entriesToRemove.size(), map.size()); - for (Entry entry : entriesToRemove) { - assertTrue(!entrySet.contains(entry)); - } - } else { - try { - entrySet.removeAll(entriesToRemove); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testEntrySetRemoveAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - if (supportsRemove) { - try { - entrySet.removeAll(null); - fail("Expected NullPointerException."); - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - entrySet.removeAll(null); - fail("Expected UnsupportedOperationException or NullPointerException."); - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testEntrySetRetainAll() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Set> entriesToRetain = - singleton(entrySet.iterator().next()); - if (supportsRemove) { - boolean shouldRemove = (entrySet.size() > entriesToRetain.size()); - boolean didRemove = entrySet.retainAll(entriesToRetain); - assertEquals(shouldRemove, didRemove); - assertEquals(entriesToRetain.size(), map.size()); - for (Entry entry : entriesToRetain) { - assertTrue(entrySet.contains(entry)); - } - } else { - try { - entrySet.retainAll(entriesToRetain); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testEntrySetRetainAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - if (supportsRemove) { - try { - entrySet.retainAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - entrySet.retainAll(null); - // We have to tolerate a successful return (Sun bug 4802647) - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testEntrySetClear() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - if (supportsClear) { - entrySet.clear(); - assertTrue(entrySet.isEmpty()); - } else { - try { - entrySet.clear(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testEntrySetAddAndAddAll() { - final Map map = makeEitherMap(); - - Set> entrySet = map.entrySet(); - final Entry entryToAdd = mapEntry(null, null); - try { - entrySet.add(entryToAdd); - fail("Expected UnsupportedOperationException or NullPointerException."); - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - assertInvariants(map); - - try { - entrySet.addAll(singleton(entryToAdd)); - fail("Expected UnsupportedOperationException or NullPointerException."); - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - assertInvariants(map); - } - - public void testEntrySetSetValue() { - // TODO: Investigate the extent to which, in practice, maps that support - // put() also support Entry.setValue(). - if (!supportsPut || !supportsEntrySetValue) { - return; - } - - final Map map; - final V valueToSet; - try { - map = makePopulatedMap(); - valueToSet = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Entry entry = entrySet.iterator().next(); - final V oldValue = entry.getValue(); - final V returnedValue = entry.setValue(valueToSet); - assertEquals(oldValue, returnedValue); - assertTrue(entrySet.contains( - mapEntry(entry.getKey(), valueToSet))); - assertEquals(valueToSet, map.get(entry.getKey())); - assertInvariants(map); - } - - public void testEntrySetSetValueSameValue() { - - // TODO: Investigate the extent to which, in practice, maps that support - // put() also support Entry.setValue(). - if (!supportsPut || !supportsEntrySetValue) { - return; - } - - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set> entrySet = map.entrySet(); - Entry entry = entrySet.iterator().next(); - final V oldValue = entry.getValue(); - final V returnedValue = entry.setValue(oldValue); - assertEquals(oldValue, returnedValue); - assertTrue(entrySet.contains( - mapEntry(entry.getKey(), oldValue))); - assertEquals(oldValue, map.get(entry.getKey())); - assertInvariants(map); - } - - public void testEntrySetIteratorLastHasNext() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - Iterator> iter = map.entrySet().iterator(); - for(int i = 0; i < map.size(); i++) - iter.next(); - assertFalse(iter.hasNext()); - } - - public void testEntrySetIteratorLastNext() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - Iterator> iter = map.entrySet().iterator(); - for(int i = 0; i < map.size(); i++) - iter.next(); - try { - iter.next(); - } - catch(NoSuchElementException e) { - // Expected - } - } - - public void testEqualsForEqualMap() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - assertEquals(map, map); - assertEquals(makePopulatedMap(), map); - assertTrue(!map.equals(Collections.emptyMap())); - //no-inspection ObjectEqualsNull - assertTrue(!map.equals(null)); - } - - public void testEqualsForLargerMap() { - if (!supportsPut) { - return; - } - - final Map map; - final Map largerMap; - try { - map = makePopulatedMap(); - largerMap = makePopulatedMap(); - largerMap.put(getKeyNotInPopulatedMap(), getValueNotInPopulatedMap()); - } catch (UnsupportedOperationException e) { - return; - } - - assertTrue(!map.equals(largerMap)); - } - - public void testEqualsForSmallerMap() { - if (!supportsRemove) { - return; - } - - final Map map; - final Map smallerMap; - try { - map = makePopulatedMap(); - smallerMap = new LinkedHashMap(map); -// smallerMap = makePopulatedMap(); - smallerMap.remove(smallerMap.keySet().iterator().next()); - } catch (UnsupportedOperationException e) { - return; - } - - assertTrue(!map.equals(smallerMap)); - } - - public void testEqualsForEmptyMap() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - assertEquals(map, map); - assertEquals(makeEmptyMap(), map); - assertEquals(Collections.emptyMap(), map); - assertTrue(!map.equals(Collections.emptySet())); - //noinspection ObjectEqualsNull - assertTrue(!map.equals(null)); - } - - public void testGet() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - for (Entry entry : map.entrySet()) { - assertEquals(entry.getValue(), map.get(entry.getKey())); - } - - K unmappedKey; - try { - unmappedKey = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertNull(map.get(unmappedKey)); - } - - public void testGetForEmptyMap() { - final Map map; - K unmappedKey; - try { - map = makeEmptyMap(); - unmappedKey = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertNull(map.get(unmappedKey)); - } - - public void testGetNull() { - Map map = makeEitherMap(); - if (allowsNullKeys) { - if (allowsNullValues) { - // TODO: decide what to test here. - } else { - assertEquals(map.containsKey(null), map.get(null) != null); - } - } else { - try { - map.get(null); - } catch (NullPointerException optional) { - } - } - assertInvariants(map); - } - - public void testHashCode() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - } - - public void testHashCodeForEmptyMap() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - } - - public void testPutNewKey() { - final Map map = makeEitherMap(); - final K keyToPut; - final V valueToPut; - try { - keyToPut = getKeyNotInPopulatedMap(); - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - if (supportsPut) { - int initialSize = map.size(); - V oldValue = map.put(keyToPut, valueToPut); - assertEquals(valueToPut, map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(valueToPut)); - assertEquals(initialSize + 1, map.size()); - assertNull(oldValue); - } else { - try { - map.put(keyToPut, valueToPut); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testPutExistingKey() { - final Map map; - final K keyToPut; - final V valueToPut; - try { - map = makePopulatedMap(); - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - keyToPut = map.keySet().iterator().next(); - if (supportsPut) { - int initialSize = map.size(); - map.put(keyToPut, valueToPut); - assertEquals(valueToPut, map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(valueToPut)); - assertEquals(initialSize, map.size()); - } else { - try { - map.put(keyToPut, valueToPut); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testPutNullKey() { - if (!supportsPut) { - return; - } - final Map map = makeEitherMap(); - final V valueToPut; - try { - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - if (allowsNullKeys) { - final V oldValue = map.get(null); - final V returnedValue = map.put(null, valueToPut); - assertEquals(oldValue, returnedValue); - assertEquals(valueToPut, map.get(null)); - assertTrue(map.containsKey(null)); - assertTrue(map.containsValue(valueToPut)); - } else { - try { - map.put(null, valueToPut); - fail("Expected RuntimeException"); - } catch (RuntimeException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testPutNullValue() { - if (!supportsPut) { - return; - } - final Map map = makeEitherMap(); - final K keyToPut; - try { - keyToPut = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - if (allowsNullValues) { - int initialSize = map.size(); - final V oldValue = map.get(keyToPut); - final V returnedValue = map.put(keyToPut, null); - assertEquals(oldValue, returnedValue); - assertNull(map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(null)); - assertEquals(initialSize + 1, map.size()); - } else { - try { - map.put(keyToPut, null); - fail("Expected RuntimeException"); - } catch (RuntimeException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testPutNullValueForExistingKey() { - if (!supportsPut) { - return; - } - final Map map; - final K keyToPut; - try { - map = makePopulatedMap(); - keyToPut = map.keySet().iterator().next(); - } catch (UnsupportedOperationException e) { - return; - } - if (allowsNullValues) { - int initialSize = map.size(); - final V oldValue = map.get(keyToPut); - final V returnedValue = map.put(keyToPut, null); - assertEquals(oldValue, returnedValue); - assertNull(map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(null)); - assertEquals(initialSize, map.size()); - } else { - try { - map.put(keyToPut, null); - fail("Expected RuntimeException"); - } catch (RuntimeException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testPutAllNewKey() { - final Map map = makeEitherMap(); - final K keyToPut; - final V valueToPut; - try { - keyToPut = getKeyNotInPopulatedMap(); - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - final Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); - if (supportsPut) { - int initialSize = map.size(); - map.putAll(mapToPut); - assertEquals(valueToPut, map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(valueToPut)); - assertEquals(initialSize + 1, map.size()); - } else { - try { - map.putAll(mapToPut); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testPutAllExistingKey() { - final Map map; - final K keyToPut; - final V valueToPut; - try { - map = makePopulatedMap(); - valueToPut = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - keyToPut = map.keySet().iterator().next(); - final Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); - int initialSize = map.size(); - if (supportsPut) { - map.putAll(mapToPut); - assertEquals(valueToPut, map.get(keyToPut)); - assertTrue(map.containsKey(keyToPut)); - assertTrue(map.containsValue(valueToPut)); - } else { - try { - map.putAll(mapToPut); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertEquals(initialSize, map.size()); - assertInvariants(map); - } - - public void testRemove() { - final Map map; - final K keyToRemove; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - keyToRemove = map.keySet().iterator().next(); - if (supportsRemove) { - int initialSize = map.size(); - V expectedValue = map.get(keyToRemove); - V oldValue = map.remove(keyToRemove); - assertEquals(expectedValue, oldValue); - assertTrue(!map.containsKey(keyToRemove)); - assertEquals(initialSize - 1, map.size()); - } else { - try { - map.remove(keyToRemove); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testRemoveMissingKey() { - final Map map; - final K keyToRemove; - try { - map = makePopulatedMap(); - keyToRemove = getKeyNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - if (supportsRemove) { - int initialSize = map.size(); - assertNull(map.remove(keyToRemove)); - assertEquals(initialSize, map.size()); - } else { - try { - map.remove(keyToRemove); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testSize() { - assertInvariants(makeEitherMap()); - } - - public void testKeySetClear() { - final Map map; - try { - map = makeEitherMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set keySet = map.keySet(); - if (supportsClear) { - keySet.clear(); - assertTrue(keySet.isEmpty()); - } else { - try { - keySet.clear(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testKeySetRemoveAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set keySet = map.keySet(); - if (supportsRemove) { - try { - keySet.removeAll(null); - fail("Expected NullPointerException."); - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - keySet.removeAll(null); - fail("Expected UnsupportedOperationException or NullPointerException."); - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testKeySetRetainAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Set keySet = map.keySet(); - if (supportsRemove) { - try { - keySet.retainAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - keySet.retainAll(null); - // We have to tolerate a successful return (Sun bug 4802647) - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testKeySetIteratorLastHasNext() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Iterator iter = map.keySet().iterator(); - for(int i = 0; i < map.size(); i++) - iter.next(); - assertFalse(iter.hasNext()); - } - - public void testKeySetIteratorLastNext() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Iterator iter = map.keySet().iterator(); - for(int i = 0; i < map.size(); i++) - iter.next(); - try { - iter.next(); - } - catch(NoSuchElementException e) { - // Expected - } - } - - public void testValues() { - final Map map; - final Collection valueCollection; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - assertInvariants(map); - - valueCollection = map.values(); - final V unmappedValue; - try { - unmappedValue = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - for (V value : valueCollection) { - assertTrue(!unmappedValue.equals(value)); - } - } - - public void testValuesIteratorRemove() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - Iterator iterator = valueCollection.iterator(); - if (supportsIteratorRemove) { - int initialSize = map.size(); - iterator.next(); - iterator.remove(); - assertEquals(initialSize - 1, map.size()); - // (We can't assert that the values collection no longer contains the - // removed value, because the underlying map can have multiple mappings - // to the same value.) - assertInvariants(map); - try { - iterator.remove(); - fail("Expected IllegalStateException."); - } catch (IllegalStateException e) { - // Expected. - } - } else { - try { - iterator.next(); - iterator.remove(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testValuesRemove() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - if (supportsRemove) { - int initialSize = map.size(); - valueCollection.remove(valueCollection.iterator().next()); - assertEquals(initialSize - 1, map.size()); - // (We can't assert that the values collection no longer contains the - // removed value, because the underlying map can have multiple mappings - // to the same value.) - } else { - try { - valueCollection.remove(valueCollection.iterator().next()); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testValuesRemoveMissing() { - final Map map; - final V valueToRemove; - try { - map = makeEitherMap(); - valueToRemove = getValueNotInPopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - int initialSize = map.size(); - if (supportsRemove) { - assertTrue(!valueCollection.remove(valueToRemove)); - } else { - try { - assertTrue(!valueCollection.remove(valueToRemove)); - } catch (UnsupportedOperationException e) { - // Tolerated. - } - } - assertEquals(initialSize, map.size()); - assertInvariants(map); - } - - public void testValuesRemoveAll() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - Set valuesToRemove = singleton(valueCollection.iterator().next()); - if (supportsRemove) { - valueCollection.removeAll(valuesToRemove); - for (V value : valuesToRemove) { - assertTrue(!valueCollection.contains(value)); - } - for (V value : valueCollection) { - assertTrue(!valuesToRemove.contains(value)); - } - } else { - try { - valueCollection.removeAll(valuesToRemove); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testValuesRemoveAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection values = map.values(); - if (supportsRemove) { - try { - values.removeAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - values.removeAll(null); - // We have to tolerate a successful return (Sun bug 4802647) - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testValuesRetainAll() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - Set valuesToRetain = singleton(valueCollection.iterator().next()); - if (supportsRemove) { - valueCollection.retainAll(valuesToRetain); - for (V value : valuesToRetain) { - assertTrue(valueCollection.contains(value)); - } - for (V value : valueCollection) { - assertTrue(valuesToRetain.contains(value)); - } - } else { - try { - valueCollection.retainAll(valuesToRetain); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testValuesRetainAllNullFromEmpty() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection values = map.values(); - if (supportsRemove) { - try { - values.retainAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException e) { - // Expected. - } - } else { - try { - values.retainAll(null); - // We have to tolerate a successful return (Sun bug 4802647) - } catch (UnsupportedOperationException e) { - // Expected. - } catch (NullPointerException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testValuesClear() { - final Map map; - try { - map = makePopulatedMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Collection valueCollection = map.values(); - if (supportsClear) { - valueCollection.clear(); - assertTrue(valueCollection.isEmpty()); - } else { - try { - valueCollection.clear(); - fail("Expected UnsupportedOperationException."); - } catch (UnsupportedOperationException e) { - // Expected. - } - } - assertInvariants(map); - } - - public void testValuesIteratorLastHasNext() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Iterator iter = map.values().iterator(); - for(int i = 0; i < map.size(); i++) - iter.next(); - assertFalse(iter.hasNext()); - } - - public void testValuesIteratorLastNext() { - final Map map; - try { - map = makeEmptyMap(); - } catch (UnsupportedOperationException e) { - return; - } - - Iterator iter = map.values().iterator(); - for(int i = 0; i < map.size(); i++) - iter.next(); - try { - iter.next(); - } - catch(NoSuchElementException e) { - // Expected - } - } - - private static Entry mapEntry(K key, V value) { - return Collections.singletonMap(key, value).entrySet().iterator().next(); - } -} diff --git a/src/test/java/org/mapdb/MapListenerTest.java b/src/test/java/org/mapdb/MapListenerTest.java deleted file mode 100644 index 8c4fd1fe1..000000000 --- a/src/test/java/org/mapdb/MapListenerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class MapListenerTest { - - @Test public void hashMap(){ - tt(DBMaker.newMemoryDB().transactionDisable().make().getHashMap("test")); - } - - @Test public void treeMap(){ - tt(DBMaker.newMemoryDB().transactionDisable().make().getTreeMap("test")); - } - - - void tt(Bind.MapWithModificationListener m){ - final AtomicReference key = new AtomicReference(null); - final AtomicReference newVal = new AtomicReference(null); - final AtomicReference oldVal = new AtomicReference(null); - final AtomicInteger counter = new AtomicInteger(0); - - Bind.MapListener listener = new Bind.MapListener(){ - @Override public void update(Object key2, Object oldVal2, Object newVal2) { - counter.incrementAndGet(); - key.set(key2); - oldVal.set(oldVal2); - newVal.set(newVal2); - } - }; - - m.modificationListenerAdd(listener); - - //check CRUD - m.put("aa","bb"); - assertTrue(key.get()=="aa" && newVal.get()=="bb" && oldVal.get()==null && counter.get()==1); - - m.put("aa","cc"); - assertTrue(key.get()=="aa" && newVal.get()=="cc" && oldVal.get()=="bb" && counter.get()==2); - - m.remove("aa"); - assertTrue(key.get()=="aa" && newVal.get()==null && oldVal.get()=="cc" && counter.get()==3); - - //check clear() - m.put("aa","bb"); - assertTrue(key.get()=="aa" && newVal.get()=="bb" && oldVal.get()==null && counter.get()==4); - m.clear(); - assertTrue(key.get()=="aa" && newVal.get()==null && oldVal.get()=="bb" && counter.get()==5); - - - //check it was unregistered - counter.set(0); - m.modificationListenerRemove(listener); - m.put("aa","bb"); - assertEquals(0, counter.get()); - } - -} diff --git a/src/test/java/org/mapdb/PumpComparableValueTest.java b/src/test/java/org/mapdb/PumpComparableValueTest.java deleted file mode 100644 index 66ee8f39c..000000000 --- a/src/test/java/org/mapdb/PumpComparableValueTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.mapdb; - - -import java.util.Iterator; - -import org.junit.Test; -import org.mapdb.Fun.Pair; - -import static org.junit.Assert.assertEquals; - - -public class PumpComparableValueTest { - - - /** - * Test mapDB data pump mechanize - * - */ - @Test - public void run(){ - DBMaker dbMaker = DBMaker.newMemoryDB() - .transactionDisable(); - - DB mapDBStore = dbMaker.make(); - - - - final int max = 70000; - - final int pumpSize = max/10; - - // data source returning the same value max times values are NOT comparable - Iterator> entriesSourceNonComp = new Iterator>() { - int count = 0; - @Override - public void remove() {throw new IllegalArgumentException("NOT SUPPORTED");} - - @Override - public Pair next() { - count++; - - String key ="SAME KEY"; - byte []value = {1}; - - Pair ret = new Pair(key,value); - return ret; - } - - @Override - public boolean hasNext() { - return count map2 = mapDBStore.createTreeMap("non comparable values") - .pumpSource(entriesSourceNonComp) - .pumpPresort(pumpSize) - .pumpIgnoreDuplicates() - .counterEnable() - .makeStringMap(); - - assertEquals(1,map2.size()); - - } - - @Test - public void run2(){ - DBMaker dbMaker = DBMaker.newMemoryDB() - .transactionDisable(); - - DB mapDBStore = dbMaker.make(); - - - - final int max = 70000; - - final int pumpSize = max/10; - - // data source returning the same value max times values are NOT comparable - Iterator> entriesSourceNonComp = new Iterator>() { - int count = 0; - @Override - public void remove() {throw new IllegalArgumentException("NOT SUPPORTED");} - - @Override - public Pair next() { - count++; - - String key = ""+count; - byte []value = {1}; - - Pair ret = new Pair(key,value); - return ret; - } - - @Override - public boolean hasNext() { - return count map2 = mapDBStore.createTreeMap("non comparable values") - .pumpSource(entriesSourceNonComp) - .pumpPresort(pumpSize) - .pumpIgnoreDuplicates() - .counterEnable() - .makeStringMap(); - - assertEquals(max,map2.size()); - - - } - - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/PumpTest.java b/src/test/java/org/mapdb/PumpTest.java deleted file mode 100644 index 30ba391db..000000000 --- a/src/test/java/org/mapdb/PumpTest.java +++ /dev/null @@ -1,392 +0,0 @@ -package org.mapdb; - - -import org.junit.Ignore; -import org.junit.Test; - -import java.util.*; - -import static org.junit.Assert.*; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class PumpTest { - - @Test - public void copy(){ - DB db1 = new DB(new StoreHeap()); - Map m = db1.getHashMap("test"); - for(int i=0;i<1000;i++){ - m.put(i, "aa"+i); - } - - DB db2 = DBMaker.newMemoryDB().make(); - Pump.copy(db1,db2); - - Map m2 = db2.getHashMap("test"); - for(int i=0;i<1000;i++){ - assertEquals("aa"+i, m.get(i)); - } - - } - - DB makeDB(int i){ - switch(i){ - case 0: return DBMaker.newAppendFileDB(UtilsTest.tempDbFile()).deleteFilesAfterClose().snapshotEnable().make(); - case 1: return DBMaker.newMemoryDB().snapshotEnable().make(); - case 2: return DBMaker.newMemoryDB().snapshotEnable().transactionDisable().make(); - case 3: return DBMaker.newMemoryDB().snapshotEnable().makeTxMaker().makeTx(); - case 4: return new DB(new StoreHeap()); - } - throw new IllegalArgumentException(""+i); - } - final int dbmax = 5; - - - @Test @Ignore - public void copy_all_stores_simple(){ - for(int srcc=0;srcc list = new ArrayList(max); - for(Integer i=0;i sorted = Pump.sort(list.iterator(),false, max/20, - Fun.COMPARATOR, Serializer.INTEGER); - - Integer counter=0; - while(sorted.hasNext()){ - assertEquals(counter++, sorted.next()); - } - assertEquals(max,counter); - - - } - - - @Test public void presort_duplicates(){ - final Integer max = 10000; - List list = new ArrayList(max); - for(Integer i=0;i sorted = Pump.sort(list.iterator(),true, max/20, - Fun.COMPARATOR, Serializer.INTEGER); - - Integer counter=0; - while(sorted.hasNext()){ - Object v = sorted.next(); - assertEquals(counter++, v); - } - assertEquals(max,counter); - - - } - - @Test public void build_treeset(){ - final int max = 10000; - List list = new ArrayList(max); - for(Integer i=max-1;i>=0;i--) list.add(i); - - Engine e = new StoreHeap(); - DB db = new DB(e); - - Set s = db.createTreeSet("test") - .nodeSize(8) - .pumpSource(list.iterator()) - .make(); - - Iterator iter =s.iterator(); - - Integer count = 0; - while(iter.hasNext()){ - assertEquals(count++, iter.next()); - } - - for(Integer i:list){ - assertTrue(""+i,s.contains(i)); - } - - assertEquals(max, s.size()); - } - - - @Test public void build_treeset_ignore_duplicates(){ - final int max = 10000; - List list = new ArrayList(max); - for(Integer i=max-1;i>=0;i--){ - list.add(i); - list.add(i); - } - - Engine e = new StoreHeap(); - DB db = new DB(e); - - Set s = db.createTreeSet("test") - .nodeSize(8) - .pumpSource(list.iterator()) - .pumpIgnoreDuplicates() - .make(); - - Iterator iter =s.iterator(); - - Integer count = 0; - while(iter.hasNext()){ - assertEquals(count++, iter.next()); - } - - for(Integer i:list){ - assertTrue(""+i,s.contains(i)); - } - - assertEquals(max, s.size()); - } - - - @Test public void build_treemap(){ - final int max = 10000; - List list = new ArrayList(max); - for(Integer i=max-1;i>=0;i--) list.add(i); - - Engine e = new StoreHeap(); - DB db = new DB(e); - - Fun.Function1 valueExtractor = new Fun.Function1() { - @Override - public Object run(Integer integer) { - return integer*100; - } - }; - - - Map s = db.createTreeMap("test") - .nodeSize(6) - .pumpSource(list.iterator(),valueExtractor) - .make(); - - - Iterator iter =s.keySet().iterator(); - - Integer count = 0; - while(iter.hasNext()){ - assertEquals(count++, iter.next()); - } - - for(Integer i:list){ - assertEquals(i * 100, s.get(i)); - } - - assertEquals(max, s.size()); - } - - @Test public void build_treemap_ignore_dupliates(){ - final int max = 10000; - List list = new ArrayList(max); - for(Integer i=max-1;i>=0;i--){ - list.add(i); - list.add(i); - } - - Engine e = new StoreHeap(); - DB db = new DB(e); - - Fun.Function1 valueExtractor = new Fun.Function1() { - @Override - public Object run(Integer integer) { - return integer*100; - } - }; - - - Map s = db.createTreeMap("test") - .nodeSize(6) - .pumpSource(list.iterator(),valueExtractor) - .pumpIgnoreDuplicates() - .make(); - - - Iterator iter =s.keySet().iterator(); - - Integer count = 0; - while(iter.hasNext()){ - assertEquals(count++, iter.next()); - } - - for(Integer i:list){ - assertEquals(i * 100, s.get(i)); - } - - assertEquals(max, s.size()); - } - - - - @Test(expected = IllegalArgumentException.class) - public void build_treemap_fails_with_unsorted(){ - List a = Arrays.asList(1,2,3,4,4,5); - DB db = new DB(new StoreHeap()); - db.createTreeSet("test").pumpSource(a.iterator()).make(); - } - - @Test(expected = IllegalArgumentException.class) - public void build_treemap_fails_with_unsorted2(){ - List a = Arrays.asList(1,2,3,4,3,5); - DB db = new DB(new StoreHeap()); - db.createTreeSet("test").pumpSource(a.iterator()).make(); - } - - - @Test public void uuid_reversed(){ - List u = new ArrayList(); - Random r = new Random(); - for(int i=0;i<1e6;i++) u.add(new UUID(r.nextLong(),r.nextLong())); - Set sorted = new TreeSet(Collections.reverseOrder(Fun.COMPARATOR)); - sorted.addAll(u); - - Iterator iter = u.iterator(); - iter = Pump.sort(iter,false, 10000,Collections.reverseOrder(Fun.COMPARATOR),Serializer.UUID); - Iterator iter2 = sorted.iterator(); - - while(iter.hasNext()){ - assertEquals(iter2.next(), iter.next()); - } - assertFalse(iter2.hasNext()); - } - - - @Test public void merge_with_duplicates(){ - List u = new ArrayList(); - for(long i=0;i<100;i++){ - u.add(i); - } - - Iterator res = Pump.sort(Fun.COMPARATOR,false,u.iterator(),u.iterator()); - - for(long i=0;i<100;i++){ - assertTrue(res.hasNext()); - assertEquals(i, res.next()); - assertTrue(res.hasNext()); - assertEquals(i, res.next()); - } - assertFalse(res.hasNext()); - } - @Test public void merge_without_duplicates(){ - List u = new ArrayList(); - for(long i=0;i<100;i++){ - u.add(i); - } - - Iterator res = Pump.sort(Fun.COMPARATOR,true,u.iterator(),u.iterator()); - - for(long i=0;i<100;i++){ - assertTrue(res.hasNext()); - assertEquals(i, res.next()); - } - assertFalse(res.hasNext()); - } - - - @Test public void merge(){ - Iterator i = Pump.merge( - Arrays.asList("a","b").iterator(), - Arrays.asList().iterator(), - Arrays.asList("c","d").iterator(), - Arrays.asList().iterator() - ); - - assertTrue(i.hasNext()); - assertEquals("a",i.next()); - assertTrue(i.hasNext()); - assertEquals("b",i.next()); - assertTrue(i.hasNext()); - assertEquals("c",i.next()); - assertTrue(i.hasNext()); - assertEquals("d",i.next()); - assertTrue(!i.hasNext()); - } - -} diff --git a/src/test/java/org/mapdb/Pump_InMemory_Import_Then_Save_To_Disk.java b/src/test/java/org/mapdb/Pump_InMemory_Import_Then_Save_To_Disk.java deleted file mode 100644 index de175535e..000000000 --- a/src/test/java/org/mapdb/Pump_InMemory_Import_Then_Save_To_Disk.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.mapdb; - -import java.io.File; -import java.util.Map; -import java.util.Random; - -/** - * This demonstrates using Data Pump to first create store in-memory at maximal speed, - * and than copy the store into memory - */ -//TODO Pump between stores is disabled for now, copy this back to examples once enabled -public class Pump_InMemory_Import_Then_Save_To_Disk { - - public static void main(String[] args) { - if(1==1) return; - - //create inMemory store which does not use serialization, - //and has speed comparable to `java.util` collections - DB inMemory = new DB(new StoreHeap()); - Map m = inMemory.getTreeMap("test"); - - Random r = new Random(); - //insert random stuff, keep on mind it needs to fit into memory - for(int i=0;i<10000;i++){ - m.put(r.nextInt(),"dwqas"+i); - } - - //now create on-disk store, it needs to be completely empty - File targetFile = UtilsTest.tempDbFile(); - DB target = DBMaker.newFileDB(targetFile).make(); - - Pump.copy(inMemory, target); - - inMemory.close(); - target.close(); - - } -} diff --git a/src/test/java/org/mapdb/QueuesTest.java b/src/test/java/org/mapdb/QueuesTest.java deleted file mode 100644 index 965931654..000000000 --- a/src/test/java/org/mapdb/QueuesTest.java +++ /dev/null @@ -1,137 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.util.Queue; -import java.util.concurrent.BlockingQueue; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class QueuesTest { - - - - @Test public void stack_persisted(){ - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).transactionDisable().cacheDisable().make(); - Queue stack = db.getStack("test"); - stack.add("1"); - stack.add("2"); - stack.add("3"); - stack.add("4"); - - db.close(); - db = DBMaker.newFileDB(f).transactionDisable().cacheDisable().deleteFilesAfterClose().make(); - stack = db.getStack("test"); - - assertEquals("4",stack.poll()); - assertEquals("3",stack.poll()); - assertEquals("2",stack.poll()); - assertEquals("1",stack.poll()); - assertNull(stack.poll()); - db.close(); - } - - - @Test public void queue_persisted(){ - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).transactionDisable().cacheDisable().make(); - Queue queue = db.getQueue("test"); - queue.add("1"); - queue.add("2"); - queue.add("3"); - queue.add("4"); - - db.close(); - db = DBMaker.newFileDB(f).transactionDisable().cacheDisable().deleteFilesAfterClose().make(); - queue = db.getQueue("test"); - - assertEquals("1", queue.poll()); - assertEquals("2", queue.poll()); - assertEquals("3", queue.poll()); - assertEquals("4", queue.poll()); - assertNull(queue.poll()); - db.close(); - } - - @Test public void circular_queue_persisted(){ - //i put disk limit 4 objects , - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).transactionDisable().cacheDisable().make(); - Queue queue = db.createCircularQueue("test",null, 4); - //when i put 6 objects to queue - queue.add(0); - queue.add(1); - queue.add(2); - queue.add(3); - //now deletes 0 on first - queue.add(4); - //now deletes 1 - queue.add(5); - - db.close(); - db = DBMaker.newFileDB(f).transactionDisable().cacheDisable().deleteFilesAfterClose().make(); - queue = db.getCircularQueue("test"); - - assertEquals(2, queue.poll()); - assertEquals(3, queue.poll()); - assertEquals(4, queue.poll()); - assertEquals(5, queue.poll()); - assertNull(queue.poll()); - db.close(); - - } - - @Test - public void testMapDb() throws InterruptedException { - DB database = DBMaker.newMemoryDB().make(); - BlockingQueue queue = database.getQueue( "test-queue" ); - queue.put( "test-value" ); - database.commit(); - assertThat( queue.take(), is( "test-value" ) ); - database.commit(); - database.close(); - } - - @Test(timeout=10000) - public void queueTakeRollback() throws IOException, InterruptedException { - File f = File.createTempFile("mapdb","aa"); - { - DB db = DBMaker.newFileDB(f).make(); - boolean newQueue = !db.exists("test"); - BlockingQueue queue = db.getQueue("test"); - if (newQueue) { - queue.add("abc"); - db.commit(); - } - Object x = queue.take(); - db.rollback(); - x = queue.take(); - - System.out.println("got it"); - db.close(); - } - - { - DB db = DBMaker.newFileDB(f).make(); - boolean newQueue = !db.exists("test"); - BlockingQueue queue = db.getQueue("test"); - if (newQueue) { - queue.add("abc"); - db.commit(); - } - Object x = queue.take(); - db.rollback(); - x = queue.take(); - - System.out.println("got it"); - db.commit(); - db.close(); - } - } -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/Serialization2Bean.java b/src/test/java/org/mapdb/Serialization2Bean.java deleted file mode 100644 index 12b8940ad..000000000 --- a/src/test/java/org/mapdb/Serialization2Bean.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.mapdb; - -import java.io.Serializable; - - -public class Serialization2Bean implements Serializable { - // =========================== Constants =============================== - private static final long serialVersionUID = 2757814409580877461L; - - // =========================== Attributes ============================== - private String id = "test"; - private String f1 = ""; - private String f2 = ""; - private String f3 = null; - private String f4 = ""; - private String f5 = null; - private String f6 = ""; - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((f1 == null) ? 0 : f1.hashCode()); - result = prime * result + ((f2 == null) ? 0 : f2.hashCode()); - result = prime * result + ((f3 == null) ? 0 : f3.hashCode()); - result = prime * result + ((f4 == null) ? 0 : f4.hashCode()); - result = prime * result + ((f5 == null) ? 0 : f5.hashCode()); - result = prime * result + ((f6 == null) ? 0 : f6.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Serialization2Bean other = (Serialization2Bean) obj; - if (f1 == null) { - if (other.f1 != null) { - return false; - } - } else if (!f1.equals(other.f1)) { - return false; - } - if (f2 == null) { - if (other.f2 != null) { - return false; - } - } else if (!f2.equals(other.f2)) { - return false; - } - if (f3 == null) { - if (other.f3 != null) { - return false; - } - } else if (!f3.equals(other.f3)) { - return false; - } - if (f4 == null) { - if (other.f4 != null) { - return false; - } - } else if (!f4.equals(other.f4)) { - return false; - } - if (f5 == null) { - if (other.f5 != null) { - return false; - } - } else if (!f5.equals(other.f5)) { - return false; - } - if (f6 == null) { - if (other.f6 != null) { - return false; - } - } else if (!f6.equals(other.f6)) { - return false; - } - if (id == null) { - if (other.id != null) { - return false; - } - } else if (!id.equals(other.id)) { - return false; - } - return true; - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/Serialization2Test.java b/src/test/java/org/mapdb/Serialization2Test.java deleted file mode 100644 index b5c3cd198..000000000 --- a/src/test/java/org/mapdb/Serialization2Test.java +++ /dev/null @@ -1,113 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.io.Serializable; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class Serialization2Test{ - - - @Test public void test2() throws IOException { - File index = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(index).cacheDisable().transactionDisable().make(); - - Serialization2Bean processView = new Serialization2Bean(); - - Map map = db.getHashMap("test2"); - - map.put("abc", processView); - - db.commit(); - - Serialization2Bean retProcessView = (Serialization2Bean)map.get("abc"); - assertEquals(processView, retProcessView); - - db.close(); - } - - - @Test public void test2_engine() throws IOException { - File index = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(index).cacheDisable().make(); - - Serialization2Bean processView = new Serialization2Bean(); - - long recid = db.engine.put(processView, (Serializer) db.getDefaultSerializer()); - - db.commit(); - - Serialization2Bean retProcessView = (Serialization2Bean) db.engine.get(recid, db.getDefaultSerializer()); - assertEquals(processView, retProcessView); - - db.close(); - } - - - @Test public void test3() throws IOException { - File index = UtilsTest.tempDbFile(); - - Serialized2DerivedBean att = new Serialized2DerivedBean(); - DB db = DBMaker.newFileDB(index).cacheDisable().make(); - - Map map = db.getHashMap("test"); - - map.put("att", att); - db.commit(); - db.close(); - db = DBMaker.newFileDB(index).cacheDisable().make(); - map = db.getHashMap("test"); - - - Serialized2DerivedBean retAtt = (Serialized2DerivedBean) map.get("att"); - assertEquals(att, retAtt); - } - - - - static class AAA implements Serializable { - - private static final long serialVersionUID = 632633199013551846L; - - String test = "aa"; - } - - - @Test public void testReopenWithDefrag(){ - - File f = UtilsTest.tempDbFile(); - - DB db = DBMaker.newFileDB(f) - .transactionDisable() - .cacheDisable() - .checksumEnable() - .make(); - - Map map = db.getTreeMap("test"); - map.put(1,new AAA()); - - db.compact(); - System.out.println(db.getEngine().get(Engine.CLASS_INFO_RECID, SerializerPojo.serializer)); - db.close(); - - db = DBMaker.newFileDB(f) - .transactionDisable() - .cacheDisable() - .checksumEnable() - .make(); - - map = db.getTreeMap("test"); - assertNotNull(map.get(1)); - assertEquals(map.get(1).test, "aa"); - - - db.close(); - } - -} diff --git a/src/test/java/org/mapdb/Serialized2DerivedBean.java b/src/test/java/org/mapdb/Serialized2DerivedBean.java deleted file mode 100644 index c0a935111..000000000 --- a/src/test/java/org/mapdb/Serialized2DerivedBean.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.mapdb; - -public class Serialized2DerivedBean extends Serialization2Bean { - private static final long serialVersionUID = 2071817382135925585L; - - private String d1 = "1"; - private String d2 = "2"; - private String d3 = null; - private String d4 = "4"; - private String d5 = null; - private String d6 = "6"; - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((d1 == null) ? 0 : d1.hashCode()); - result = prime * result + ((d2 == null) ? 0 : d2.hashCode()); - result = prime * result + ((d3 == null) ? 0 : d3.hashCode()); - result = prime * result + ((d4 == null) ? 0 : d4.hashCode()); - result = prime * result + ((d5 == null) ? 0 : d5.hashCode()); - result = prime * result + ((d6 == null) ? 0 : d6.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - Serialized2DerivedBean other = (Serialized2DerivedBean) obj; - if (d1 == null) { - if (other.d1 != null) - return false; - } else if (!d1.equals(other.d1)) - return false; - if (d2 == null) { - if (other.d2 != null) - return false; - } else if (!d2.equals(other.d2)) - return false; - if (d3 == null) { - if (other.d3 != null) - return false; - } else if (!d3.equals(other.d3)) - return false; - if (d4 == null) { - if (other.d4 != null) - return false; - } else if (!d4.equals(other.d4)) - return false; - if (d5 == null) { - if (other.d5 != null) - return false; - } else if (!d5.equals(other.d5)) - return false; - if (d6 == null) { - if (other.d6 != null) - return false; - } else if (!d6.equals(other.d6)) - return false; - return true; - } - - - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/SerializerBaseTest.java b/src/test/java/org/mapdb/SerializerBaseTest.java deleted file mode 100644 index bbd557239..000000000 --- a/src/test/java/org/mapdb/SerializerBaseTest.java +++ /dev/null @@ -1,746 +0,0 @@ -/******************************************************************************* - * Copyright 2010 Cees De Groot, Alex Boisvert, Jan Kotek - * - * 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 - * - * http://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. - ******************************************************************************/ -package org.mapdb; - -import org.junit.Test; - -import java.io.*; -import java.lang.reflect.Field; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.util.AbstractMap.SimpleEntry; -import java.util.*; - -import static org.junit.Assert.*; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class SerializerBaseTest{ - - - @Test public void testInt() throws IOException{ - int[] vals = { - Integer.MIN_VALUE, - 2*Short.MIN_VALUE, - -1+Short.MIN_VALUE, - 256*Short.MIN_VALUE, - Short.MIN_VALUE, - -10, -9, -8, -7, -6, -5, -4, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 127, 254, 255, 256, Short.MAX_VALUE, Short.MAX_VALUE + 1, - Short.MAX_VALUE * 2, Integer.MAX_VALUE,256*Short.MIN_VALUE, - 0x80FFFFFF //Issue #202 - }; - for (Integer i : vals) { - Object l2 = clone(i); - assertEquals(i, l2); - assertTrue(l2.getClass() == Integer.class); - } - } - - void serSize(int expected, Object val) throws IOException { - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - Serializer.BASIC.serialize(out,val); - assertEquals(expected, out.pos); - } - - @Test public void testIntSize() throws IOException { - serSize(1,Integer.MIN_VALUE); - serSize(1,Integer.MAX_VALUE); - for(int i=-9;i<=16;i++) - serSize(1,i); - serSize(2, 100); - serSize(2, -100); - serSize(3, 0xFFF); - serSize(3, -0xFFF); - serSize(4, 0xFFFFF); - serSize(4, -0xFFFFF); - serSize(5, 0xFFFFFFF); - serSize(5, -0xFFFFFFF); - } - - @Test public void testShort() throws IOException{ - for (int i = Short.MIN_VALUE;i<=Short.MAX_VALUE;i++) { - Short ii = (short)i; - Object l2 = clone(ii); - assertEquals(ii,l2); - assertTrue(l2.getClass() == Short.class); - } - } - - @Test public void testDouble() throws IOException{ - double[] vals = { - 1f, 0f, -1f, Math.PI, 255, 256, Short.MAX_VALUE, Short.MAX_VALUE + 1, -100 - }; - for (double i : vals) { - Object l2 = clone(i); - assertTrue(l2.getClass() == Double.class); - assertEquals(l2, i); - } - } - - - @Test public void testFloat() throws IOException{ - float[] vals = { - 1f, 0f, -1f, (float) Math.PI, 255, 256, Short.MAX_VALUE, Short.MAX_VALUE + 1, -100 - }; - for (float i : vals) { - Object l2 = clone(i); - assertTrue(l2.getClass() == Float.class); - assertEquals(l2, i); - } - } - - @Test public void testChar() throws IOException{ - for (int ii = Character.MIN_VALUE;ii<=Character.MAX_VALUE;ii++) { - Character i = (char)ii; - Object l2 = clone(i); - assertEquals(l2.getClass(), Character.class); - assertEquals(l2, i); - } - } - - - @Test public void testLong() throws IOException{ - long[] vals = { - 65536, - Long.MIN_VALUE, - Integer.MIN_VALUE, (long)Integer.MIN_VALUE - 1, (long)Integer.MIN_VALUE + 1, - 2* Short.MIN_VALUE * 2, - -1 + Short.MIN_VALUE, - Short.MIN_VALUE, - -10, -9, -8, -7, -6, -5, -4, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 127, 254, 255, 256, Short.MAX_VALUE, Short.MAX_VALUE + 1, - Short.MAX_VALUE * 2, Integer.MAX_VALUE, (long)Integer.MAX_VALUE + 1, Long.MAX_VALUE, - 0x80FFFFFFFFFFFFFFL, //Issue #202 - 0x8000000000000000L, - 0x7F00000000000001L - - }; - for (long i : vals) { - Object l2 = clone(i); - assertTrue(l2.getClass() == Long.class); - assertEquals(l2, i); - } - } - - @Test public void testLongSize() throws IOException { - serSize(1,Long.MIN_VALUE); - serSize(1,Long.MAX_VALUE); - for(long i=-9;i<=16;i++) - serSize(1,i); - serSize(2, 100L); - serSize(2, -100L); - serSize(3, 0xFFFL); - serSize(3, -0xFFFL); - serSize(4, 0xFFFFFL); - serSize(4, -0xFFFFFL); - serSize(5, 0xFFFFFFFL); - serSize(5, -0xFFFFFFFL); - serSize(6, 0xFFFFFFFFFL); - serSize(6, -0xFFFFFFFFFL); - serSize(7, 0xFFFFFFFFFFFL); - serSize(7, -0xFFFFFFFFFFFL); - serSize(8, 0xFFFFFFFFFFFFFL); - serSize(8, -0xFFFFFFFFFFFFFL); - serSize(9, 0xFFFFFFFFFFFFFFFL); - serSize(9, -0xFFFFFFFFFFFFFFFL); - } - - @Test public void testBoolean1() throws IOException{ - Object l2 = clone(true); - assertTrue(l2.getClass() == Boolean.class); - assertEquals(l2, true); - - Object l22 = clone(false); - assertTrue(l22.getClass() == Boolean.class); - assertEquals(l22, false); - - } - - @Test public void testString() throws IOException{ - String l2 = (String) clone("Abcd"); - assertEquals(l2, "Abcd"); - } - - @Test public void testBigString() throws IOException{ - String bigString = ""; - for (int i = 0; i < 1e4; i++) - bigString += i % 10; - String l2 = clone(bigString); - assertEquals(l2, bigString); - } - - - @Test public void testNoArgumentConstructorInJavaSerialization() throws ClassNotFoundException, IOException { - SimpleEntry a = new SimpleEntry(1, "11"); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new ObjectOutputStream(out).writeObject(a); - ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); - SimpleEntry a2 = (SimpleEntry) in.readObject(); - assertEquals(a, a2); - } - - - @Test public void testArrayList() throws ClassNotFoundException, IOException { - Collection c = new ArrayList(); - for (int i = 0; i < 200; i++) - c.add(i); - assertEquals(c, clone((c))); - for (int i = 0; i < 2000; i++) - c.add(i); - assertEquals(c, clone((c))); - } - - @Test public void testLinkedList() throws ClassNotFoundException, IOException { - Collection c = new java.util.LinkedList(); - for (int i = 0; i < 200; i++) - c.add(i); - assertEquals(c, clone((c))); - for (int i = 0; i < 2000; i++) - c.add(i); - assertEquals(c, clone((c))); - } - - - - @Test public void testTreeSet() throws ClassNotFoundException, IOException { - Collection c = new TreeSet(); - for (int i = 0; i < 200; i++) - c.add(i); - assertEquals(c, clone((c))); - for (int i = 0; i < 2000; i++) - c.add(i); - assertEquals(c, clone((c))); - } - - @Test public void testHashSet() throws ClassNotFoundException, IOException { - Collection c = new HashSet(); - for (int i = 0; i < 200; i++) - c.add(i); - assertEquals(c, clone((c))); - for (int i = 0; i < 2000; i++) - c.add(i); - assertEquals(c, clone((c))); - } - - @Test public void testLinkedHashSet() throws ClassNotFoundException, IOException { - Collection c = new LinkedHashSet(); - for (int i = 0; i < 200; i++) - c.add(i); - assertEquals(c, clone((c))); - for (int i = 0; i < 2000; i++) - c.add(i); - assertEquals(c, clone((c))); - } - - @Test public void testHashMap() throws ClassNotFoundException, IOException { - Map c = new HashMap(); - for (int i = 0; i < 200; i++) - c.put(i, i + 10000); - assertEquals(c, clone((c))); - for (int i = 0; i < 2000; i++) - c.put(i, i + 10000); - assertEquals(c, clone((c))); - } - - @Test public void testTreeMap() throws ClassNotFoundException, IOException { - Map c = new TreeMap(); - for (int i = 0; i < 200; i++) - c.put(i, i + 10000); - assertEquals(c, clone((c))); - for (int i = 0; i < 2000; i++) - c.put(i, i + 10000); - assertEquals(c, clone((c))); - } - - @Test public void testLinkedHashMap() throws ClassNotFoundException, IOException { - Map c = new LinkedHashMap(); - for (int i = 0; i < 200; i++) - c.put(i, i + 10000); - assertEquals(c, clone((c))); - for (int i = 0; i < 2000; i++) - c.put(i, i + 10000); - assertEquals(c, clone((c))); - } - - - @Test public void testProperties() throws ClassNotFoundException, IOException { - Properties c = new Properties(); - for (int i = 0; i < 200; i++) - c.put(i, i + 10000); - assertEquals(c, clone((c))); - for (int i = 0; i < 2000; i++) - c.put(i, i + 10000); - assertEquals(c, clone((c))); - } - - - @Test public void testClass() throws IOException{ - assertEquals(clone(String.class), String.class); - assertEquals(clone(long[].class), long[].class); - } - - - @Test public void testUnicodeString() throws ClassNotFoundException, IOException { - String s = "Ciudad Bolíva"; - assertEquals(clone(s), s); - } - - @Test public void testPackedLongCollection() throws ClassNotFoundException, IOException { - ArrayList l1 = new ArrayList(); - l1.add(0L); - l1.add(1L); - l1.add(0L); - assertEquals(l1, clone((l1))); - l1.add(-1L); - assertEquals(l1, clone((l1))); - } - - @Test public void testNegativeLongsArray() throws ClassNotFoundException, IOException { - long[] l = new long[] { -12 }; - Object deserialize = clone((l)); - assertTrue(Arrays.equals(l, (long[]) deserialize)); - } - - - @Test public void testNegativeIntArray() throws ClassNotFoundException, IOException { - int[] l = new int[] { -12 }; - Object deserialize = clone((l)); - assertTrue(Arrays.equals(l, (int[]) deserialize)); - } - - - @Test public void testNegativeShortArray() throws ClassNotFoundException, IOException { - short[] l = new short[] { -12 }; - Object deserialize = clone((l)); - assertTrue(Arrays.equals(l, (short[]) deserialize)); - } - - @Test public void testBooleanArray() throws ClassNotFoundException, IOException { - boolean[] l = new boolean[] { true,false }; - Object deserialize = clone((l)); - assertTrue(Arrays.equals(l, (boolean[]) deserialize)); - } - - @Test public void testDoubleArray() throws ClassNotFoundException, IOException { - double[] l = new double[] { Math.PI, 1D }; - Object deserialize = clone((l)); - assertTrue(Arrays.equals(l, (double[]) deserialize)); - } - - @Test public void testFloatArray() throws ClassNotFoundException, IOException { - float[] l = new float[] { 1F, 1.234235F }; - Object deserialize = clone((l)); - assertTrue(Arrays.equals(l, (float[]) deserialize)); - } - - @Test public void testByteArray() throws ClassNotFoundException, IOException { - byte[] l = new byte[] { 1,34,-5 }; - Object deserialize = clone((l)); - assertTrue(Arrays.equals(l, (byte[]) deserialize)); - } - - @Test public void testCharArray() throws ClassNotFoundException, IOException { - char[] l = new char[] { '1','a','&' }; - Object deserialize = clone((l)); - assertTrue(Arrays.equals(l, (char[]) deserialize)); - } - - - @Test public void testDate() throws IOException{ - Date d = new Date(6546565565656L); - assertEquals(d, clone((d))); - d = new Date(System.currentTimeMillis()); - assertEquals(d, clone((d))); - } - - @Test public void testBigDecimal() throws IOException{ - BigDecimal d = new BigDecimal("445656.7889889895165654423236"); - assertEquals(d, clone((d))); - d = new BigDecimal("-53534534534534445656.7889889895165654423236"); - assertEquals(d, clone((d))); - } - - @Test public void testBigInteger() throws IOException{ - BigInteger d = new BigInteger("4456567889889895165654423236"); - assertEquals(d, clone((d))); - d = new BigInteger("-535345345345344456567889889895165654423236"); - assertEquals(d, clone((d))); - } - - - @Test public void testUUID() throws IOException, ClassNotFoundException { - //try a bunch of UUIDs. - for(int i = 0; i < 1000;i++) - { - UUID uuid = UUID.randomUUID(); - assertEquals(uuid, clone((uuid))); - } - } - - @Test public void testArray() throws IOException { - Object[] o = new Object[]{"A",Long.valueOf(1),Long.valueOf(2),Long.valueOf(3), Long.valueOf(3)}; - Object[] o2 = (Object[]) clone(o); - assertArrayEquals(o,o2); - } - - - @Test public void test_issue_38() throws IOException { - String[] s = new String[5]; - String[] s2 = (String[]) clone(s); - assertArrayEquals(s, s2); - assertTrue(s2.toString().contains("[Ljava.lang.String")); - } - - @Test public void test_multi_dim_array() throws IOException { - int[][] arr = new int[][]{{11,22,44},{1,2,34}}; - int[][] arr2= (int[][]) clone(arr); - assertArrayEquals(arr,arr2); - } - - @Test public void test_multi_dim_large_array() throws IOException { - int[][] arr1 = new int[3000][]; - double[][] arr2 = new double[3000][]; - for(int i=0;i<3000;i++){ - arr1[i]= new int[]{i,i+1}; - arr2[i]= new double[]{i,i+1}; - } - assertArrayEquals(arr1, (Object[]) clone(arr1)); - assertArrayEquals(arr2, (Object[]) clone(arr2)); - } - - - @Test public void test_multi_dim_array2() throws IOException { - Object[][] arr = new Object[][]{{11,22,44},{1,2,34}}; - Object[][] arr2= (Object[][]) clone(arr); - assertArrayEquals(arr,arr2); - } - - - @Test public void test_static_objects() throws IOException { - for(Object o:new SerializerBase().mapdb_all.keySet()){ - if(o instanceof SerializerBase.Deser) - continue; - assertTrue(o==clone(o)); - } - } - - @Test public void test_singleton_reverse() throws IOException { - SerializerBase b = new SerializerBase(); - assertEquals(b.mapdb_all.size(), b.mapdb_reverse.size()); - } - - - @Test public void test_tuple_key_serializer() throws IOException { - assertEquals(BTreeKeySerializer.ARRAY2, clone(BTreeKeySerializer.ARRAY2)); - assertEquals(BTreeKeySerializer.ARRAY3, clone(BTreeKeySerializer.ARRAY3)); - assertEquals(BTreeKeySerializer.ARRAY4, clone(BTreeKeySerializer.ARRAY4)); - } - - - - - - @Test public void test_strings_var_sizes() throws IOException { - for(int i=0;i<50;i++){ - String s = UtilsTest.randomString(i); - assertEquals(s, clone((s))); - } - } - - - @Test public void test_extended_chars() throws IOException { - String s = "人口, 日本、人口, 日本の公式統計"; - assertEquals(s,clone((s))); - } - - @Test public void testBooleanArray2() throws IOException { - for(int i=0;i<1000;i++){ - boolean[] b = new boolean[i]; - for(int j=0;j E clone(E value) throws IOException { - return clone2(value,(Serializer)Serializer.BASIC); - } - - /** clone value using serialization */ - public static E clone2(E value, Serializer serializer) { - try{ - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - serializer.serialize(out, value); - DataIO.DataInputByteBuffer in = new DataIO.DataInputByteBuffer(ByteBuffer.wrap(out.copyBytes()), 0); - - return serializer.deserialize(in,out.pos); - }catch(IOException ee){ - throw new IOError(ee); - } - } - - public static class SerializerBaseTestWithJUDataStreams extends SerializerBaseTest{ - @Override - E clone(E value) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Serializer.BASIC.serialize(new DataOutputStream(out), value); - - return (E) Serializer.BASIC.deserialize(new DataInputStream(new ByteArrayInputStream(out.toByteArray())),-1); - } - } - - @SuppressWarnings({ "rawtypes" }) - @Test public void testHeaderUnique() throws IllegalAccessException { - SerializerBase b = new SerializerBase(); - Class c = SerializerBase.Header.class; - Set s = new TreeSet(); - for (Field f : c.getDeclaredFields()) { - f.setAccessible(true); - int value = f.getInt(null); - - assertTrue("Value already used: " + value, !s.contains(value)); - s.add(value); - - if(value!=SerializerBase.Header.POJO && value!=SerializerBase.Header.NAMED) - assertNotNull("deser does not contain value: "+value + " - "+f.getName(), b.headerDeser[value]); - - } - assertTrue(!s.isEmpty()); - } - - @SuppressWarnings({ "rawtypes" }) - @Test public void testHeaderUniqueMapDB() throws IllegalAccessException { - Class c = SerializerBase.HeaderMapDB.class; - Set s = new TreeSet(); - for (Field f : c.getDeclaredFields()) { - f.setAccessible(true); - int value = f.getInt(null); - - assertTrue("Value already used: " + value, !s.contains(value)); - s.add(value); - - } - assertTrue(!s.isEmpty()); - } - - - @Test public void test_All_Serializer_Fields_Serializable() throws IllegalAccessException, IOException { - SerializerBase b = new SerializerBase(); - for(Field f:Serializer.class.getDeclaredFields()){ - Object a = f.get(null); - assertTrue("field: "+f.getName(), b.mapdb_all.containsKey(a)); - assertTrue("field: "+f.getName(),a == clone(a)); - } - } - - @Test public void test_All_Hasher_Fields_Serializable() throws IllegalAccessException, IOException { - SerializerBase b = new SerializerBase(); - for(Field f:Hasher.class.getDeclaredFields()){ - Object a = f.get(null); - assertTrue("field: "+f.getName(), b.mapdb_all.containsKey(a)); - assertTrue("field: "+f.getName(),a == clone(a)); - } - } - - - @Test public void test_All_Fun_Fields_Serializable() throws IllegalAccessException, IOException { - SerializerBase b = new SerializerBase(); - for(Field f:Fun.class.getDeclaredFields()){ - Object a = f.get(null); - assertTrue("field: "+f.getName(), b.mapdb_all.containsKey(a)); - assertTrue("field: "+f.getName(),a == clone(a)); - } - } - - - @Test public void test_All_BTreeKeySerializer_Fields_Serializable() throws IllegalAccessException, IOException { - SerializerBase b = new SerializerBase(); - for(Field f:BTreeKeySerializer.class.getDeclaredFields()){ - Object a = f.get(null); - assertTrue("field: "+f.getName(), b.mapdb_all.containsKey(a)); - assertTrue("field: "+f.getName(),a == clone(a)); - } - } - @Test public void test_Named(){ - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).make(); - Map map = db.getTreeMap("map"); - - Map map2 = db.getTreeMap("map2"); - map2.put("some","stuff"); - map.put("map2_",map2); - - Queue stack = db.getStack("stack"); - stack.add("stack"); - map.put("stack_",stack); - - Atomic.Long along = db.getAtomicLong("along"); - along.set(111L); - map.put("along_",along); - - db.commit(); - db.close(); - - db = DBMaker.newFileDB(f).deleteFilesAfterClose().make(); - map = db.getTreeMap("map"); - - map2 = (Map) map.get("map2_"); - assertNotNull(map2); - assertEquals(map2.get("some"),"stuff"); - - stack = (Queue) map.get("stack_"); - assertEquals("stack",stack.poll()); - - along = (Atomic.Long) map.get("along_"); - assertEquals(111L,along.get()); - } - - @Test public void test_atomic_ref_serializable(){ - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).make(); - Map map = db.getTreeMap("map"); - - long recid = db.getEngine().put(11L, Serializer.LONG); - Atomic.Long l = new Atomic.Long(db.getEngine(),recid); - map.put("long",l); - - recid = db.getEngine().put(11, Serializer.INTEGER); - Atomic.Integer i = new Atomic.Integer(db.getEngine(),recid); - map.put("int",i); - - recid = db.getEngine().put(true, Serializer.BOOLEAN); - Atomic.Boolean b = new Atomic.Boolean(db.getEngine(),recid); - map.put("bool",b); - - recid = db.getEngine().put("aa", Serializer.STRING_NOSIZE); - Atomic.String s = new Atomic.String(db.getEngine(),recid); - map.put("str",s); - - recid = db.getEngine().put("hovnocuc", db.getDefaultSerializer()); - Atomic.Var v = new Atomic.Var(db.getEngine(),recid,db.getDefaultSerializer()); - map.put("var",v); - - db.commit(); - db.close(); - db = DBMaker.newFileDB(f).deleteFilesAfterClose().make(); - map = db.getTreeMap("map"); - - l = (Atomic.Long) map.get("long"); - assertEquals(11L, l.get()); - - i = (Atomic.Integer) map.get("int"); - assertEquals(11, i.get()); - - b = (Atomic.Boolean) map.get("bool"); - assertEquals(true, b.get()); - - s = (Atomic.String) map.get("str"); - assertEquals("aa", s.get()); - - v = (Atomic.Var) map.get("var"); - assertEquals("hovnocuc", v.get()); - assertEquals(db.getDefaultSerializer(), v.serializer); - } - - - @Test public void array_comparator() throws IOException { - Fun.ArrayComparator c = new Fun.ArrayComparator(new Comparator[]{Fun.REVERSE_COMPARATOR, Fun.COMPARATOR, Fun.COMPARATOR}); - assertEquals(c,clone(c)); - } - - - - @Test public void object_stack_issue232_n2() throws IOException { - Integer i = 1; - Fun.Pair t = new Fun.Pair(i,i); - assertEquals(t,clone(t)); - } - - Long one = 10000L; - Long two = 20000L; - - @Test public void object_stack_array() throws IOException { - Object[] c = new Object[4]; - c[0]=c; - c[1]=one; - c[2]=two; - c[3]=one; - c = clone(c); - assertTrue(c==c[0]); - assertEquals(one, c[1]); - assertEquals(two, c[2]); - assertEquals(one, c[3]); - assertTrue(c[1]==c[3]); - } - - @Test public void object_stack_list() throws IOException { - for(List c : Arrays.asList(new ArrayList(), new LinkedList())){ - c.add(c); - c.add(one); - c.add(two); - c.add(one); - c = clone(c); - assertTrue(c==c.get(0)); - assertEquals(one, c.get(1)); - assertEquals(two, c.get(2)); - assertEquals(one, c.get(3)); - assertTrue(c.get(1)==c.get(3)); - } - } - - @Test public void object_stack_set() throws IOException { - for(Set c : Arrays.asList(new HashSet(), new LinkedHashSet())){ - c.add(c); - c = clone(c); - assertTrue(c.iterator().next()==c); - } - } - - - @Test public void object_stack_map() throws IOException { - for(Map c : Arrays.asList(new HashMap(), new LinkedHashMap(), new TreeMap(), new Properties())){ - c.put(one,c); - c.put(two,one); - c = clone(c); - assertTrue(c.get(one)==c); - assertEquals(one,c.get(two)); - Iterator i = c.keySet().iterator(); - Object one_ = i.next(); - if(one_!=c.get(two)) - one_ = i.next(); - assertTrue(one_==c.get(two)); - } - } - - @Test public void serializer_compression_wrapper() throws IOException { - Object o = new Serializer.CompressionWrapper(Serializer.LONG); - assertEquals(o, clone(o)); - } - - @Test public void mapdb_singletons_equalent_after_clone() throws IOException { - SerializerBase b = new SerializerBase(); - for(Object o:b.mapdb_all.keySet()){ - if(o instanceof SerializerBase.Deser) - continue; - assertTrue(o==clone(o)); - } - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/SerializerPojoTest.java b/src/test/java/org/mapdb/SerializerPojoTest.java deleted file mode 100644 index 48c9a9a5c..000000000 --- a/src/test/java/org/mapdb/SerializerPojoTest.java +++ /dev/null @@ -1,440 +0,0 @@ -package org.mapdb; - - -import junit.framework.TestCase; - -import javax.security.sasl.RealmCallback; -import javax.swing.*; -import java.io.*; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.GregorianCalendar; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicInteger; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class SerializerPojoTest extends TestCase { - - SerializerPojo p = new SerializerPojo(new CopyOnWriteArrayList()); - - enum Order - { - ASCENDING, - DESCENDING - } - private byte[] serialize(Object i) throws IOException { - DataIO.DataOutputByteArray in = new DataIO.DataOutputByteArray(); - p.serialize(in, i); - return in.copyBytes(); - } - - private Object deserialize(byte[] buf) throws IOException { - return p.deserialize(new DataIO.DataInputByteBuffer(ByteBuffer.wrap(buf),0),-1); - } - - - public void testEnum() throws Exception{ - Order o = Order.ASCENDING; - o = (Order) UtilsTest.clone(o, p); - assertEquals(o,Order.ASCENDING ); - assertEquals(o.ordinal(),Order.ASCENDING .ordinal()); - assertEquals(o.name(),Order.ASCENDING .name()); - - o = Order.DESCENDING; - o = (Order) UtilsTest.clone(o, p); - assertEquals(o,Order.DESCENDING ); - assertEquals(o.ordinal(),Order.DESCENDING .ordinal()); - assertEquals(o.name(),Order.DESCENDING .name()); - - } - - - static class Extr implements Externalizable{ - - public Extr(){} - - int aaa = 11; - String l = "agfa"; - - @Override public void writeExternal(ObjectOutput out) throws IOException { - out.writeObject(l); - out.writeInt(aaa); - - } - - @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - l = (String) in.readObject(); - aaa = in.readInt()+1; - - } - } - - public void testExternalizable() throws Exception{ - Extr e = new Extr(); - e.aaa = 15; - e.l = "pakla"; - - e = (Extr) deserialize(serialize(e)); - assertEquals(e.aaa, 16); //was incremented during serialization - assertEquals(e.l,"pakla"); - - } - - - static class Bean1 implements Serializable { - - private static final long serialVersionUID = -2549023895082866523L; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Bean1 bean1 = (Bean1) o; - - if (Double.compare(bean1.doubleField, doubleField) != 0) return false; - if (Float.compare(bean1.floatField, floatField) != 0) return false; - if (intField != bean1.intField) return false; - if (longField != bean1.longField) return false; - if (field1 != null ? !field1.equals(bean1.field1) : bean1.field1 != null) return false; - if (field2 != null ? !field2.equals(bean1.field2) : bean1.field2 != null) return false; - - return true; - } - - - protected String field1 = null; - protected String field2 = null; - - protected int intField = Integer.MAX_VALUE; - protected long longField = Long.MAX_VALUE; - protected double doubleField = Double.MAX_VALUE; - protected float floatField = Float.MAX_VALUE; - - transient int getCalled = 0; - transient int setCalled = 0; - - public String getField2() { - getCalled++; - return field2; - } - - public void setField2(String field2) { - setCalled++; - this.field2 = field2; - } - - Bean1(String field1, String field2) { - this.field1 = field1; - this.field2 = field2; - } - - Bean1() { - } - } - - static class Bean2 extends Bean1 { - - private static final long serialVersionUID = 8376654194053933530L; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - Bean2 bean2 = (Bean2) o; - - if (field3 != null ? !field3.equals(bean2.field3) : bean2.field3 != null) return false; - - return true; - } - - @Override - public int hashCode() { - return field3 != null ? field3.hashCode() : 0; - } - - private String field3 = null; - - Bean2(String field1, String field2, String field3) { - super(field1, field2); - this.field3 = field3; - } - - Bean2() { - } - } - - - - Bean1 b = new Bean1("aa", "bb"); - Bean2 b2 = new Bean2("aa", "bb", "cc"); - - public void testGetFieldValue1() throws Exception { - assertEquals("aa", p.getFieldValue(new SerializerPojo.FieldInfo("field1",false,String.class.getName(),b.getClass()), b)); - } - - public void testGetFieldValue2() throws Exception { - assertEquals("bb", p.getFieldValue(new SerializerPojo.FieldInfo("field2",false,String.class.getName(),b.getClass()), b)); - assertEquals(0, b.getCalled); - } - - public void testGetFieldValue3() throws Exception { - assertEquals("aa", p.getFieldValue(new SerializerPojo.FieldInfo("field1",false,String.class.getName(),b2.getClass()), b2)); - } - - public void testGetFieldValue4() throws Exception { - assertEquals("bb", p.getFieldValue(new SerializerPojo.FieldInfo("field2",false,String.class.getName(),b2.getClass()), b2)); - assertEquals(0, b2.getCalled); - } - - public void testGetFieldValue5() throws Exception { - assertEquals("cc", p.getFieldValue(new SerializerPojo.FieldInfo("field3",false,String.class.getName(),b2.getClass()), b2)); - } - - - - public void testSerializable() throws Exception { - - assertEquals(b, UtilsTest.clone(b, p)); - } - - - public void testRecursion() throws Exception { - AbstractMap.SimpleEntry b = new AbstractMap.SimpleEntry("abcd", null); - b.setValue(b.getKey()); - - AbstractMap.SimpleEntry bx = (AbstractMap.SimpleEntry) UtilsTest.clone(b, p); - assertEquals(bx, b); - assert (bx.getKey() == bx.getValue()); - - } - - public void testRecursion2() throws Exception { - AbstractMap.SimpleEntry b = new AbstractMap.SimpleEntry("abcd", null); - b.setValue(b); - - AbstractMap.SimpleEntry bx = (AbstractMap.SimpleEntry) UtilsTest.clone(b, p); - assertTrue(bx == bx.getValue()); - assertEquals(bx.getKey(), "abcd"); - - } - - - public void testRecursion3() throws Exception { - ArrayList l = new ArrayList(); - l.add("123"); - l.add(l); - - ArrayList l2 = (ArrayList) UtilsTest.clone(l, p); - - assertTrue(l2.size() == 2); - assertEquals(l2.get(0), "123"); - assertTrue(l2.get(1) == l2); - } - - public void testPersistedSimple() throws Exception { - - File f = UtilsTest.tempDbFile(); - DB r1 = DBMaker.newFileDB(f).make(); - long recid = r1.engine.put("AA",r1.getDefaultSerializer()); - r1.commit(); - r1.close(); - - r1 = DBMaker.newFileDB(f).make(); - - String a2 = (String) r1.engine.get(recid, r1.getDefaultSerializer()); - r1.close(); - assertEquals("AA", a2); - - } - - - public void testPersisted() throws Exception { - Bean1 b1 = new Bean1("abc", "dcd"); - File f = UtilsTest.tempDbFile(); - DB r1 = DBMaker.newFileDB(f).make(); - long recid = r1.engine.put(b1, r1.getDefaultSerializer()); - r1.commit(); - r1.close(); - - r1 = DBMaker.newFileDB(f).make(); - - Bean1 b2 = (Bean1) r1.engine.get(recid,r1.getDefaultSerializer()); - r1.close(); - assertEquals(b1, b2); - - } - - - public void test_write_object_advanced_serializationm(){ - Object[] o = new Object[]{ - new GregorianCalendar(1,1,1), - new JLabel("aa") - }; - - for(Object oo:o){ - DB db = DBMaker.newMemoryDB().make(); - long recid = db.engine.put(oo, db.getDefaultSerializer()); - assertEquals(oo, db.engine.get(recid, db.getDefaultSerializer())); - } - - } - - - public static class test_pojo_reload_TestClass implements Serializable - { - private String name; - - public test_pojo_reload_TestClass(String name) { - this.name = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - test_pojo_reload_TestClass that = (test_pojo_reload_TestClass) o; - - if (name != null ? !name.equals(that.name) : that.name != null) return false; - - return true; - } - - @Override - public int hashCode() { - return name != null ? name.hashCode() : 0; - } - } - - /** @author Jan Sileny */ - public void test_pojo_reload() throws IOException { - - File f = UtilsTest.tempDbFile(); - DB db = DBMaker.newFileDB(f).make(); - Set set = db.getHashSet("testSerializerPojo"); - set.add(new test_pojo_reload_TestClass("test")); - db.commit(); -// System.out.println(((SerializerPojo)db.defaultSerializer).registered); - int prevsize = ((SerializerPojo)db.getDefaultSerializer()).registered.size(); - - db.close(); - - db = DBMaker.newFileDB(f).deleteFilesAfterClose().make(); - set = db.getHashSet("testSerializerPojo"); - set.add(new test_pojo_reload_TestClass("test2")); - db.commit(); - int newsize = ((SerializerPojo)db.getDefaultSerializer()).registered.size(); -// System.out.println(((SerializerPojo)db.defaultSerializer).registered); - db.close(); - - assertEquals(prevsize, newsize); - } - - - public static class test_transient implements Serializable{ - transient int aa = 11; - transient String ss = "aa"; - int bb = 11; - } - - public void test_transient(){ - test_transient t = new test_transient(); - t.aa = 12; - t.ss = "bb"; - t.bb = 13; - t = (test_transient) UtilsTest.clone(t, p); - assertEquals(0,t.aa); - assertEquals(null,t.ss); - assertEquals(13,t.bb); - } - - public void test_transient2(){ - test_transient t = new test_transient(); - t.aa = 12; - t.ss = "bb"; - t.bb = 13; - - t = outputStreamClone(t); - assertEquals(0,t.aa); - assertEquals(null,t.ss); - assertEquals(13,t.bb); - } - - /** clone value using serialization */ - public static E outputStreamClone(E value){ - try{ - ByteArrayOutputStream out = new ByteArrayOutputStream(); - new ObjectOutputStream(out).writeObject(value); - ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); - return (E) in.readObject(); - }catch(Exception ee){ - throw new IOError(ee); - } - } - - - public void testIssue177() throws UnknownHostException { - DB db = DBMaker.newMemoryDB().cacheDisable().make(); - InetAddress value = InetAddress.getByName("127.0.0.1"); - long recid = db.engine.put(value, db.getDefaultSerializer()); - Object value2 = db.engine.get(recid,db.getDefaultSerializer()); - assertEquals(value,value2); - } - - //this can not be serialized, it alwaes throws exception on serialization - static final class RealClass implements Serializable, Externalizable{ - @Override - public void writeExternal(ObjectOutput out) throws IOException { - throw new Error(); - } - - @Override - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - throw new Error(); - } - } - - //this is placeholder which gets serialized instead - static final class PlaceHolder implements Serializable{ - - } - - public void test_interlizeceptors(){ - final AtomicInteger counter = new AtomicInteger(); - Fun.Function1 ser = new Fun.Function1() { - @Override - public Object run(Object o) { - if(o instanceof RealClass) { - counter.incrementAndGet(); - return new PlaceHolder(); - } - return o; - } - }; - Fun.Function1 deser = new Fun.Function1() { - @Override - public Object run(Object o) { - if(o instanceof PlaceHolder) { - counter.incrementAndGet(); - return new RealClass(); - } - return o; - } - }; - - - p.serializerTransformAdd(ser,deser); - - Object o = UtilsTest.clone(new RealClass(), p); - assertTrue(o instanceof RealClass); - assertEquals(2,counter.get()); - } - -} diff --git a/src/test/java/org/mapdb/SerializerTest.java b/src/test/java/org/mapdb/SerializerTest.java deleted file mode 100644 index bcfc14966..000000000 --- a/src/test/java/org/mapdb/SerializerTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Random; -import java.util.UUID; - -import static org.junit.Assert.*; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class SerializerTest { - - @Test public void UUID2(){ - UUID u = UUID.randomUUID(); - assertEquals(u, SerializerBaseTest.clone2(u,Serializer.UUID)); - } - - @Test public void string_ascii(){ - String s = "adas9 asd9009asd"; - assertEquals(s,SerializerBaseTest.clone2(s,Serializer.STRING_ASCII)); - s = ""; - assertEquals(s, SerializerBaseTest.clone2(s,Serializer.STRING_ASCII)); - s = " "; - assertEquals(s, SerializerBaseTest.clone2(s,Serializer.STRING_ASCII)); - } - - @Test public void compression_wrapper() throws IOException { - byte[] b = new byte[100]; - new Random().nextBytes(b); - Serializer ser = new Serializer.CompressionWrapper(Serializer.BYTE_ARRAY); - assertArrayEquals(b, SerializerBaseTest.clone2(b,ser)); - - b = Arrays.copyOf(b, 10000); - assertArrayEquals(b, SerializerBaseTest.clone2(b,ser)); - - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - ser.serialize(out,b); - assertTrue(out.pos<1000); - } -} diff --git a/src/test/java/org/mapdb/StoreAppendTest.java b/src/test/java/org/mapdb/StoreAppendTest.java deleted file mode 100644 index a06a4d800..000000000 --- a/src/test/java/org/mapdb/StoreAppendTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; - -import static org.junit.Assert.*; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class StoreAppendTest extends EngineTest{ - - - File f = UtilsTest.tempDbFile(); - - - @Override - protected E openEngine() { - return (E) new StoreAppend(f.getPath()); - } - - @Test - public void compact_file_deleted(){ - StoreAppend engine = new StoreAppend(f.getPath()); - File f1 = engine.getFileFromNum(0); - File f2 = engine.getFileFromNum(1); - long recid = engine.put(111L, Serializer.LONG); - Long i=0L; - for(;i< StoreAppend.FILE_MASK+1000; i+=8){ - engine.update(recid, i, Serializer.LONG); - } - i-=8; - - assertTrue(f1.exists()); - assertTrue(f2.exists()); - assertEquals(i, engine.get(recid, Serializer.LONG)); - - engine.commit(); - assertTrue(f1.exists()); - assertTrue(f2.exists()); - assertEquals(i, engine.get(recid, Serializer.LONG)); - - engine.compact(); - assertFalse(f1.exists()); - assertTrue(f2.exists()); - assertEquals(i, engine.get(recid, Serializer.LONG)); - - f1.delete(); - f2.delete(); - - engine.close(); - } - - @Test public void delete_files_after_close(){ - File f = UtilsTest.tempDbFile(); - File f2 = new File(f.getPath()+".0"); - DB db = DBMaker.newAppendFileDB(f).deleteFilesAfterClose().make(); - - db.getHashMap("test").put("aa","bb"); - db.commit(); - assertTrue(f2.exists()); - db.close(); - assertFalse(f2.exists()); - } - - @Test public void header_created() throws IOException { - //check offset - assertEquals(StoreAppend.LAST_RESERVED_RECID, e.maxRecid); - assertEquals(1+8+2*StoreAppend.LAST_RESERVED_RECID, e.currPos); - RandomAccessFile raf = new RandomAccessFile(e.getFileFromNum(0),"r"); - //check header - raf.seek(0); - assertEquals(StoreAppend.HEADER, raf.readLong()); - //check reserved recids - for(int recid=1;recid<=StoreAppend.LAST_RESERVED_RECID;recid++){ - assertEquals(0, e.index.getLong(recid*8)); - assertEquals(recid+StoreAppend.RECIDP,raf.read()); //packed long - assertEquals(0+StoreAppend.SIZEP,raf.read()); //packed long - } - - assertEquals(StoreAppend.END+StoreAppend.RECIDP,raf.read()); //packed long - //check recid iteration - assertFalse(e.getFreeRecids().hasNext()); - } - - @Test public void put(){ - long oldPos = e.currPos; - Volume vol = e.currVolume; - assertEquals(0, vol.getUnsignedByte(oldPos)); - - long maxRecid = e.maxRecid; - long value = 11111111111111L; - long recid = e.put(value,Serializer.LONG); - assertEquals(maxRecid+1, recid); - assertEquals(e.maxRecid, recid); - - assertEquals(recid+StoreAppend.RECIDP, vol.getPackedLong(oldPos)); - assertEquals(8+StoreAppend.SIZEP, vol.getPackedLong(oldPos+1)); - assertEquals(value, vol.getLong(oldPos+2)); - - assertEquals(Long.valueOf(oldPos+1), e.indexInTx.get(recid)); - e.commit(); - assertEquals(oldPos+1, e.index.getLong(recid*8)); - - } - - - @Override public void large_record_larger(){ - //TODO ignored test - } -} diff --git a/src/test/java/org/mapdb/StoreDirectFreeSpaceTest.java b/src/test/java/org/mapdb/StoreDirectFreeSpaceTest.java deleted file mode 100644 index 8b21ffe43..000000000 --- a/src/test/java/org/mapdb/StoreDirectFreeSpaceTest.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.*; - -import static org.junit.Assert.*; - -public class StoreDirectFreeSpaceTest { - - final long max = 100000; - - final Map> longStacks = new TreeMap >(); - - /** mock longStacks so their page allocations wont mess up tests */ - StoreDirect stub = new StoreDirect(null){ - { - structuralLock.lock(); - } - - private Deque stackList(long ioList) { - if(longStacks.get(ioList)==null) longStacks.put(ioList, new LinkedList()); - return longStacks.get(ioList); - } - - @Override - protected long longStackTake(long ioList, boolean recursive) { - Long r = stackList(ioList).pollLast(); - return r!=null?r:0; - } - - - @Override - protected void longStackPut(long ioList, long offset, boolean recursive) { - maxUsedIoList = Math.max(maxUsedIoList, ioList); - stackList(ioList).add(offset); - } - }; - - void fill(long... n){ - for(int i=0;i>>48; //size - b[i*2+1] = size; - b[0]+=size - (i==a.length-1 ? 0: 8); - b[i*2+2] = a[i] & StoreDirect.MASK_OFFSET; //offset - } - - assertArrayEquals(n, b); - } - - long size(long i){ - return StoreDirect.size2ListIoRecid(i); - } - - @Test - public void simpleTake(){ - fill(1,2); - assertEquals(2, stub.longStackTake(1,false)); - } - - @Test - public void simpleSpaceAlloc(){ - long ioList = size(16); - fill(ioList,32); - check(16, 16,32); - } - - @Test - public void simpleGrow(){ - check(32,32,16); - check(16,16,48); - } - - @Test - public void largeGrow(){ - int size = StoreDirect.MAX_REC_SIZE+100; - check(size, StoreDirect.MAX_REC_SIZE, 16, 108, 16+StoreDirect.MAX_REC_SIZE+1); - } - - @Test public void reuse_after_full(){ - stub.physSize = max; - fill(size(1600),320); - check(1600,1600,320); - } - - @Test public void split_after_full(){ - stub.physSize = max; - fill(size(3200),320); - check(1600,1600,320); - check(1600,1600,320+1600); - assertLongStacksEmpty(); - } - - void assertLongStacksEmpty() { - for(Deque d:longStacks.values()){ - if(!d.isEmpty()) fail(); - } - } - - - @Test public void multi_linked(){ - int size = 16000+16000; - fill(size(16000),100000, size(16000),200000); - //TODO - } - - @Test public void in_memory_compact(){ - for(DB d: Arrays.asList(DBMaker.newMemoryDB().cacheDisable().make(), - DBMaker.newMemoryDB().transactionDisable().cacheDisable().make())){ - Map m = d.getTreeMap("aa"); - for(Integer i=0;i<10000;i++){ - m.put(i,i*10); - } - d.commit(); - d.compact(); - for(Integer i=0;i<10000;i++){ - assertEquals(i*10, m.get(i)); - } - } - } - - -} diff --git a/src/test/java/org/mapdb/StoreDirectTest.java b/src/test/java/org/mapdb/StoreDirectTest.java deleted file mode 100644 index 035f42e79..000000000 --- a/src/test/java/org/mapdb/StoreDirectTest.java +++ /dev/null @@ -1,468 +0,0 @@ -package org.mapdb; - - -import org.junit.Before; -import org.junit.Test; - -import java.io.File; -import java.io.IOError; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static org.junit.Assert.*; -import static org.mapdb.StoreDirect.*; - -@SuppressWarnings({"rawtypes","unchecked"}) -public class StoreDirectTest extends EngineTest{ - - @Override boolean canRollback(){return false;} - - File f = UtilsTest.tempDbFile(); - - - static final long IO_RECID = StoreDirect.IO_FREE_RECID+32; - - @Override protected E openEngine() { - return (E) new StoreDirect(f.getPath()); - } - - int countIndexRecords(){ - int ret = 0; - for(int pos = StoreDirect.IO_USER_START; pos getLongStack(long ioRecid){ - - ArrayList ret =new ArrayList(); - - long pagePhysid = e.index.getLong(ioRecid) & StoreDirect.MASK_OFFSET; - long pageOffset = e.index.getLong(ioRecid) >>>48; - - - while(pagePhysid!=0){ - - while(pageOffset>=8){ - //System.out.println(pagePhysid + " - "+pageOffset); - final Long l = e.phys.getSixLong(pagePhysid + pageOffset); - pageOffset-=6; - ret.add(l); - } - //System.out.println(ret); - //read location of previous page - pagePhysid = e.phys.getLong(pagePhysid) & StoreDirect.MASK_OFFSET; - pageOffset = (e.phys.getLong(pagePhysid) >>>48) - 6; - } - - return ret; - } - - - @Test - public void phys_append_alloc(){ - e.structuralLock.lock(); - long[] ret = e.physAllocate(100,true,false); - long expected = 100L<<48 | 16L; - assertArrayEquals(new long[]{expected}, ret); - } - - @Test - public void phys_append_alloc_link2(){ - e.structuralLock.lock(); - long[] ret = e.physAllocate(100 + MAX_REC_SIZE,true,false); - long exp1 = MASK_LINKED |((long)MAX_REC_SIZE)<<48 | 16L; - long exp2 = 108L<<48 | (16L+MAX_REC_SIZE+1); - assertArrayEquals(new long[]{exp1, exp2}, ret); - } - - @Test - public void phys_append_alloc_link3(){ - e.structuralLock.lock(); - long[] ret = e.physAllocate(100 + MAX_REC_SIZE*2,true,false); - long exp1 = MASK_LINKED | ((long)MAX_REC_SIZE)<<48 | 16L; - long exp2 = MASK_LINKED | ((long)MAX_REC_SIZE)<<48 | (16L+MAX_REC_SIZE+1); - long exp3 = ((long)116)<<48 | (16L+MAX_REC_SIZE*2+2); - - assertArrayEquals(new long[]{exp1, exp2, exp3}, ret); - } - - @Test public void second_rec_pos_round_to_16(){ - e.structuralLock.lock(); - long[] ret= e.physAllocate(1,true,false); - assertArrayEquals(new long[]{1L<<48|16L},ret); - ret= e.physAllocate(1,true,false); - assertArrayEquals(new long[]{1L<<48|32L},ret); - - } - - - @Test public void test_index_record_delete(){ - long recid = e.put(1000L, Serializer.LONG); - e.commit(); - assertEquals(1, countIndexRecords()); - e.delete(recid,Serializer.LONG); - e.commit(); - assertEquals(0, countIndexRecords()); - e.structuralLock.lock(); - assertEquals(recid*8 + StoreDirect.IO_USER_START, e.freeIoRecidTake(true)); - } - - @Test public void test_size2IoList(){ - long old= StoreDirect.IO_FREE_RECID; - for(int size=1;size<= StoreDirect.MAX_REC_SIZE;size++){ - - long ioListRecid = size2ListIoRecid(size); - assertTrue(ioListRecid> StoreDirect.IO_FREE_RECID); - assertTrue(ioListRecid< StoreDirect.IO_USER_START); - - assertEquals(ioListRecid,old+(size%16==1?8:0)); - - old=ioListRecid; - } - } - - - - @Test public void test_index_record_delete_and_reusef(){ - long recid = e.put(1000L, Serializer.LONG); - e.commit(); - assertEquals(1, countIndexRecords()); - assertEquals(LAST_RESERVED_RECID+1, recid); - e.delete(recid,Serializer.LONG); - e.commit(); - assertEquals(0, countIndexRecords()); - long recid2 = e.put(1000L, Serializer.LONG); - e.commit(); - //test that previously deleted index slot was reused - assertEquals(recid, recid2); - assertEquals(1, countIndexRecords()); - assertTrue(0!=e.index.getLong(recid*8+ StoreDirect.IO_USER_START)); - } - - - @Test public void test_index_record_delete_and_reuse_large(){ - final long MAX = 10; - - List recids= new ArrayList(); - for(int i = 0;i recids2= new ArrayList(); - for(int i = 0;i>>48); - - } - - @Test public void test_long_stack_put_take() throws IOException { - e.structuralLock.lock(); - - final long max = 150; - for(long i=1;i0;i--){ - assertEquals(i, e.longStackTake(IO_RECID,false)); - } - - assertEquals(0, getLongStack(IO_RECID).size()); - - } - - @Test public void test_long_stack_put_take_simple() throws IOException { - e.structuralLock.lock(); - e.longStackPut(IO_RECID, 111,false); - assertEquals(111L, e.longStackTake(IO_RECID,false)); - } - - - @Test public void test_basic_long_stack() throws IOException { - //dirty hack to make sure we have lock - e.structuralLock.lock(); - final long max = 150; - ArrayList list = new ArrayList(); - for(long i=1;i=1;i--){ - assertEquals(i, e.longStackTake(IO_RECID,false)); - } - } - - @Test public void test_large_long_stack() throws IOException { - //dirty hack to make sure we have lock - e.structuralLock.lock(); - final long max = 15000; - ArrayList list = new ArrayList(); - for(long i=1;i=1;i--){ - assertEquals(i, e.longStackTake(IO_RECID,false)); - } - } - - @Test public void test_basic_long_stack_no_commit() throws IOException { - //dirty hack to make sure we have lock - e.structuralLock.lock(); - final long max = 150; - for(long i=1;i=1;i--){ - assertEquals(i, e.longStackTake(IO_RECID,false)); - } - } - - @Test public void test_large_long_stack_no_commit() throws IOException { - //dirty hack to make sure we have lock - e.structuralLock.lock(); - final long max = 15000; - for(long i=1;i=1;i--){ - assertEquals(i, e.longStackTake(IO_RECID,false)); - } - } - - - - @Test public void long_stack_page_created_after_put() throws IOException { - e.structuralLock.lock(); - e.longStackPut(IO_RECID, 111,false); - e.commit(); - long pageId = e.index.getLong(IO_RECID); - assertEquals(8, pageId>>>48); - pageId = pageId & StoreDirect.MASK_OFFSET; - assertEquals(16L, pageId); - assertEquals(LONG_STACK_PREF_SIZE, e.phys.getLong(pageId)>>>48); - assertEquals(0, e.phys.getLong(pageId)& StoreDirect.MASK_OFFSET); - assertEquals(111, e.phys.getSixLong(pageId + 8)); - } - - @Test public void long_stack_put_five() throws IOException { - e.structuralLock.lock(); - e.longStackPut(IO_RECID, 111,false); - e.longStackPut(IO_RECID, 112,false); - e.longStackPut(IO_RECID, 113,false); - e.longStackPut(IO_RECID, 114,false); - e.longStackPut(IO_RECID, 115,false); - - e.commit(); - long pageId = e.index.getLong(IO_RECID); - assertEquals(8+6*4, pageId>>>48); - pageId = pageId & StoreDirect.MASK_OFFSET; - assertEquals(16L, pageId); - assertEquals(LONG_STACK_PREF_SIZE, e.phys.getLong(pageId)>>>48); - assertEquals(0, e.phys.getLong(pageId)&MASK_OFFSET); - assertEquals(111, e.phys.getSixLong(pageId + 8)); - assertEquals(112, e.phys.getSixLong(pageId + 14)); - assertEquals(113, e.phys.getSixLong(pageId + 20)); - assertEquals(114, e.phys.getSixLong(pageId + 26)); - assertEquals(115, e.phys.getSixLong(pageId + 32)); - } - - @Test public void long_stack_page_deleted_after_take() throws IOException { - e.structuralLock.lock(); - e.longStackPut(IO_RECID, 111,false); - e.commit(); - assertEquals(111L, e.longStackTake(IO_RECID,false)); - e.commit(); - assertEquals(0L, e.index.getLong(IO_RECID)); - } - - @Test public void long_stack_page_overflow() throws IOException { - e.structuralLock.lock(); - //fill page until near overflow - for(int i=0;i< StoreDirect.LONG_STACK_PREF_COUNT;i++){ - e.longStackPut(IO_RECID, 1000L+i,false); - } - e.commit(); - - //check content - long pageId = e.index.getLong(IO_RECID); - assertEquals(StoreDirect.LONG_STACK_PREF_SIZE-6, pageId>>>48); - pageId = pageId & StoreDirect.MASK_OFFSET; - assertEquals(16L, pageId); - assertEquals(StoreDirect.LONG_STACK_PREF_SIZE, e.phys.getLong(pageId)>>>48); - for(int i=0;i< StoreDirect.LONG_STACK_PREF_COUNT;i++){ - assertEquals(1000L+i, e.phys.getSixLong(pageId + 8 + i * 6)); - } - - //add one more item, this will trigger page overflow - e.longStackPut(IO_RECID, 11L,false); - e.commit(); - //check page overflowed - pageId = e.index.getLong(IO_RECID); - assertEquals(8, pageId>>>48); - pageId = pageId & StoreDirect.MASK_OFFSET; - assertEquals(16L+ StoreDirect.LONG_STACK_PREF_SIZE, pageId); - assertEquals(LONG_STACK_PREF_SIZE, e.phys.getLong(pageId)>>>48); - assertEquals(16L, e.phys.getLong(pageId)& StoreDirect.MASK_OFFSET); - assertEquals(11L, e.phys.getSixLong(pageId + 8)); - } - - - @Test public void test_constants(){ - assertTrue(StoreDirect.LONG_STACK_PREF_SIZE%16==0); - - } - - - @Test public void delete_files_after_close(){ - File f = UtilsTest.tempDbFile(); - File phys = new File(f.getPath()+StoreDirect.DATA_FILE_EXT); - - DB db = DBMaker.newFileDB(f).transactionDisable().deleteFilesAfterClose().make(); - - db.getHashMap("test").put("aa","bb"); - db.commit(); - assertTrue(f.exists()); - assertTrue(phys.exists()); - db.close(); - assertFalse(f.exists()); - assertFalse(phys.exists()); - } - - @Test public void freeSpaceWorks(){ - long oldFree = e.getFreeSize(); - long recid = e.put(new byte[10000],Serializer.BYTE_ARRAY_NOSIZE); - e.commit(); - assertEquals(oldFree, e.getFreeSize()); - e.delete(recid,Serializer.BYTE_ARRAY_NOSIZE); - assertEquals(oldFree+10000,e.getFreeSize()); - e.commit(); - assertEquals(oldFree+10000,e.getFreeSize()); - } - - - @Test public void prealloc(){ - long recid = e.preallocate(); - assertNull(e.get(recid,UtilsTest.FAIL)); - e.commit(); - assertNull(e.get(recid,UtilsTest.FAIL)); - } - - @Test public void header_index_inc() throws IOException { - e.put(new byte[10000],Serializer.BYTE_ARRAY_NOSIZE); - e.commit(); - e.close(); - - //increment store version - Volume v = Volume.volumeForFile(f,true,false,0,CC.VOLUME_SLICE_SHIFT, 0); - v.putUnsignedShort(4,StoreDirect.STORE_VERSION+1); - v.sync(); - v.close(); - - try{ - e = openEngine(); - fail(); - }catch(IOError e){ - Throwable e2 = e; - while (e2 instanceof IOError){ - e2 = e2.getCause(); - } - assertTrue(e2.getMessage().contains("version")); - } - - - - } - - @Test public void header_phys_inc() throws IOException { - e.put(new byte[10000],Serializer.BYTE_ARRAY_NOSIZE); - e.commit(); - e.close(); - - //increment store version - File phys = new File(f.getPath()+StoreDirect.DATA_FILE_EXT); - Volume v = Volume.volumeForFile(phys,true,false,0,CC.VOLUME_SLICE_SHIFT, 0); - v.putUnsignedShort(4,StoreDirect.STORE_VERSION+1); - v.sync(); - v.close(); - - try{ - e = openEngine(); - fail(); - }catch(IOError e){ - Throwable e2 = e; - while (e2 instanceof IOError){ - e2 = e2.getCause(); - } - assertTrue(e2.getMessage().contains("version")); - } - } - -} diff --git a/src/test/java/org/mapdb/StoreHeapTest.java b/src/test/java/org/mapdb/StoreHeapTest.java deleted file mode 100644 index 130f4504e..000000000 --- a/src/test/java/org/mapdb/StoreHeapTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.mapdb; - - -public class StoreHeapTest extends EngineTest{ - - - @Override - protected StoreHeap openEngine() { - return new StoreHeap(); - } - - @Override boolean canReopen(){return false;} - - @Override boolean canRollback(){return false;} - - -} diff --git a/src/test/java/org/mapdb/StoreTest.java b/src/test/java/org/mapdb/StoreTest.java deleted file mode 100644 index a41d09a71..000000000 --- a/src/test/java/org/mapdb/StoreTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.mapdb; - -import org.junit.Test; - -import java.util.Arrays; -import java.util.Random; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; - -public class StoreTest { - - @Test public void compression(){ - Store s = (Store)DBMaker.newMemoryDB() - .cacheDisable() - .transactionDisable() - .compressionEnable() - .makeEngine(); - - long size = s.getCurrSize(); - long recid = s.put(new byte[10000],Serializer.BYTE_ARRAY); - assertTrue(s.getCurrSize() - size < 200); - assertArrayEquals(new byte[10000],s.get(recid,Serializer.BYTE_ARRAY)); - } - - - @Test public void compression_random(){ - Random r = new Random(); - - for(int i=100;i<100000;i=i*2){ - Store s = (Store)DBMaker.newMemoryDB() - .cacheDisable() - .transactionDisable() - .compressionEnable() - .makeEngine(); - - long size = s.getCurrSize(); - byte[] b = new byte[i]; - r.nextBytes(b); - //grow so there is something to compress - b = Arrays.copyOfRange(b,0,i); - b = Arrays.copyOf(b,i*5); - long recid = s.put(b,Serializer.BYTE_ARRAY); - assertTrue(s.getCurrSize() - size < i*2+100); - assertArrayEquals(b,s.get(recid,Serializer.BYTE_ARRAY)); - } - } - - -} diff --git a/src/test/java/org/mapdb/StoreWALTest.java b/src/test/java/org/mapdb/StoreWALTest.java deleted file mode 100644 index c7bccaa43..000000000 --- a/src/test/java/org/mapdb/StoreWALTest.java +++ /dev/null @@ -1,192 +0,0 @@ -package org.mapdb; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import java.io.File; -import java.io.IOError; -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -import static org.junit.Assert.*; - -public class StoreWALTest extends StoreDirectTest{ - - - @Override - protected StoreWAL openEngine() { - return new StoreWAL(f.getPath()); - } - - @Override - boolean canRollback() { - return true; - } - - @Test - public void delete_files_after_close2(){ - File f = UtilsTest.tempDbFile(); - File phys = new File(f.getPath()+StoreDirect.DATA_FILE_EXT); - File wal = new File(f.getPath()+StoreWAL.TRANS_LOG_FILE_EXT); - - DB db = DBMaker.newFileDB(f).deleteFilesAfterClose().make(); - - db.getHashMap("test").put("aa","bb"); - db.commit(); - assertTrue(f.exists()); - assertTrue(phys.exists()); - assertTrue(wal.exists()); - db.getHashMap("test").put("a12a","bb"); - assertTrue(wal.exists()); - db.close(); - assertFalse(f.exists()); - assertFalse(phys.exists()); - assertFalse(wal.exists()); - } - - - - @Test public void header_index_ver() throws IOException { - e.put(new byte[10000],Serializer.BYTE_ARRAY_NOSIZE); - e.commit(); - e.close(); - - //increment store version - File index = new File(f.getPath()+StoreWAL.TRANS_LOG_FILE_EXT); - Volume v = Volume.volumeForFile(index,true,false,0,CC.VOLUME_SLICE_SHIFT,0); - v.ensureAvailable(100); - v.putInt(0,StoreWAL.HEADER); - v.putUnsignedShort(4,StoreDirect.STORE_VERSION+1); - v.putLong(8,StoreWAL.LOG_SEAL); - v.putInt(80,1); - v.sync(); - v.close(); - - try{ - e = openEngine(); - fail(); - }catch(IOError e){ - Throwable e2 = e; - while (e2 instanceof IOError){ - e2 = e2.getCause(); - } - assertTrue(e2.getMessage().contains("version")); - } - } - - - @Test public void replay_good_log() throws IOException { - - final AtomicBoolean replay = new AtomicBoolean(true); - - StoreWAL wal = new StoreWAL(f.getPath()){ - @Override - protected void replayLogFile() { - if(replay.get()) - super.replayLogFile(); - else - throw new IllegalAccessError(); - } - }; - - DB db = new DB(wal); - - Map m = db.getHashMap("map"); - - //fill map and commit - int max = (int) 1e5; - for(int i=0;i?|\\".toCharArray() + var seed2 = seed + val b = StringBuilder(size) + for (i in 0..size - 1) { + b.append(chars[Math.abs(seed2) % chars.size]) + seed2 = 31 * seed2 + DataIO.intHash(seed2) + } + return b.toString() + } + + private val tempDir = System.getProperty("java.io.tmpdir"); + + /* + * Create temporary file in temp folder. All associated db files will be deleted on JVM exit. + */ + @JvmStatic fun tempFile(): File { + fun sanitize(name:String) = java.lang.String(name).replaceAll("[^a-zA-Z0-9_\\.]+","") + + val stackTrace = Thread.currentThread().stackTrace; + val elem = stackTrace[2]; + val prefix = "mapdbTest_"+sanitize(elem.className)+"-"+sanitize(elem.methodName)+"-"+elem.lineNumber+"_" + while(true){ + val file = File(tempDir+File.separator+prefix+System.currentTimeMillis()+"_"+Math.random()); + if(file.exists().not()) { + file.deleteOnExit() + return file + } + } + } + + @JvmStatic fun tempNotExistFile():File{ + val f = tempFile() + f.delete() + assertFalse(f.exists()) + return f + } + + @JvmStatic fun tempDir(): File { + val ret = tempFile() + ret.mkdir() + return ret + } + + @JvmStatic fun tempDelete(file: File){ + val name = file.getName() + for (f2 in file.getParentFile().listFiles()!!) { + if (f2.name.startsWith(name)) + tempDeleteRecur(f2) + } + tempDeleteRecur(file) + } + + @JvmStatic fun tempDeleteRecur(file: File) { + if(file.isDirectory){ + for(child in file.listFiles()) + tempDeleteRecur(child) + } + file.delete() + } + + + object Serializer_ILLEGAL_ACCESS: Serializer { + + + override fun serializedType() = throw AssertionError("No access") + override fun serialize(out: DataOutput2, value: Any) { + throw AssertionError("Should not access this serializer") + } + + override fun deserialize(dataIn: DataInput2): Any { + throw AssertionError("Should not access this serializer") + } + + } + + /** how many hours should unit tests run? Controlled by: + * `mvn test -Dmdbtest=2` + * @return test scale + */ + @JvmStatic fun testScale(): Int { + val prop = System.getProperty("mdbtest")?:"0"; + try { + return Integer.valueOf(prop); + } catch(e:NumberFormatException) { + return 0; + } + } + + @JvmStatic fun testRuntime(minutes:Int): Long = 3000L + minutes * 60 * 1000 * testScale() + + + @JvmStatic fun nowPlusMinutes(minutes: Double): Long { + return System.currentTimeMillis() + 2000 + (testScale() * 1000.0 * 60.0 * minutes).toLong() + } + + + @JvmStatic fun shortTest(): Boolean { + return testScale() == 0 + } + + /* clone value using serialization */ + @JvmStatic fun clone(value: E, serializer: Serializer<*>, out:DataOutput2 = DataOutput2ByteArray()): E { + @Suppress("UNCHECKED_CAST") + (serializer as Serializer).serialize(out, value) + val in2 = DataInput2ByteArray(out.copyBytes()) + return serializer.deserialize(in2) + } + + /* clone value using java serialization */ + @JvmStatic fun cloneJavaSerialization(value: E): E { + val out = ByteArrayOutputStream() + val out2 = ObjectOutputStream(out) + out2.writeObject(value) + out2.flush() + + val in2 = ByteArrayInputStream(out.toByteArray()) + @Suppress("UNCHECKED_CAST") + return ObjectInputStream(in2).readObject() as E + } + + @JvmStatic fun serializedSize(value: E, serializer: Serializer<*>, out:DataOutput2 = DataOutput2ByteArray()): Int { + @Suppress("UNCHECKED_CAST") + (serializer as Serializer).serialize(out, value) + return out.copyBytes().size; + } + + + fun fork(count:Int=1, body:(i:Int)->Unit){ + val finish = async(count=count, body=body) + finish() + } + + + fun async(count:Int=1, body:(i:Int)->Unit):()->Unit{ + val exec = executor(count) + val wait = CountDownLatch(1) + val exception = AtomicReference() + for(i in 0 until count){ + exec.submit { + try{ + wait.await() + body(i) + }catch(e:Throwable){ + e.printStackTrace() + exception.set(e) + } + } + } + wait.countDown() + exec.shutdown() + return { + + while(!exec.awaitTermination(1, TimeUnit.MILLISECONDS)){ + val e = exception.get() + if(e!=null) + throw AssertionError(e) + } + } + } + + + + fun forkExecutor(exec: ExecutorService, count:Int=1, body:(i:Int)->Unit){ + val exception = AtomicReference() + val wait = CountDownLatch(1) + val tasks = (0 until count).map{i-> + exec.submit { + try{ + wait.await() + body(i) + }catch(e:Throwable){ + exception.set(e) + } + } + }.toMutableSet() + wait.countDown() + + //await for all tasks to finish + while(!tasks.isEmpty()){ + val iter = tasks.iterator() + while(iter.hasNext()){ + if(iter.next().isDone) + iter.remove() + } + + val e = exception.get() + if(e!=null) + throw AssertionError(e) + Thread.sleep(1) + } + } + + + fun assertAllZero(old: ByteArray) { + val z = 0.toByte() + for( o in old){ + if(o!=z) + throw AssertionError() + } + } + + /** executor service with deamon threads, so Unit Test JVM can exit */ + fun executor(threadCount:Int=1): ScheduledExecutorService { + return Executors.newScheduledThreadPool(threadCount) { r-> + val t = Thread(r) + t.isDaemon = true + t + } + } + + + fun reflectionInvokeMethod(obj:Any, name:String, clazz:Class<*> = obj.javaClass):E{ + val method = clazz.getDeclaredMethod(name) + method.isAccessible = true + return method.invoke(obj) as E + } + + + fun reflectionGetField(obj:Any, name:String, clazz:Class<*> = obj.javaClass):E{ + val field = clazz.getDeclaredField(name) + field.isAccessible = true + return field.get(obj) as E + } + + fun reflectionSetField(obj:Any, newValue:Any?, name:String, clazz:Class<*> = obj.javaClass){ + val field = clazz.getDeclaredField(name) + field.isAccessible = true + field.set(obj, newValue) + } + + + /** + * Catches expected exception, rethrows everything else. + * + * Compared to [kotlin.test.assertFailsWith] does not swallow wrong exceptions, better for debuging + * + */ + inline fun assertFailsWith(exceptionClass: kotlin.reflect.KClass, block: () -> Unit) { + try { + block() + fail("Expected exception ${exceptionClass}") + } catch (e: Throwable) { + if (exceptionClass.isInstance(e)) { + @Suppress("UNCHECKED_CAST") + return + } + throw e + } + } + + + inline fun withTempFile(f:(file:File)->Unit){ + val file = TT.tempFile() + file.delete(); + try{ + f(file) + }finally { + if(!file.delete()) + file.deleteOnExit() + } + } + + + inline fun withTempDir(f:(dir:File)->Unit){ + val dir = TT.tempDir() + try{ + f(dir) + }finally { + dir.deleteRecursively() + } + } + + + object byteArrayGen : Gen { + override fun random(): Sequence = generateSequence { + randomByteArray(random.nextInt(100)) + } + + override fun constants(): Iterable = listOf( + ByteArray(0), byteArrayOf(-1, -1), byteArrayOf(1, 2, 3), byteArrayOf(0)) + + } + + + data class TestPojo(val a:String, val b:String):Serializable + + /** random generator of any type */ + object anyGen: Gen{ + override fun constants(): Iterable { + return listOf(1,2, 4L, listOf(1,2,4), "aa", TestPojo("aa", "bb")) + } + + override fun random(): Sequence = + generateSequence { + Math.random() + } + + } + + fun genFor(cl: Class<*>?): Gen = when (cl) { + + java.lang.Integer::class.java -> Gen.int() + java.lang.Long::class.java -> Gen.long() + java.lang.Double::class.java -> Gen.double() + java.lang.String::class.java -> Gen.string() + ByteArray::class.java -> byteArrayGen + null -> anyGen // generic serializers + + else -> throw AssertionError("unknown class $cl") + } + + inline fun withBool(run:(b: AtomicBoolean)->Unit) { + val b = AtomicBoolean(true) + try { + run.invoke(b) + }finally { + b.set(false) + } + } +/* + + fun installValidateReadWriteLock(v:Validate, fieldName:String){ + val origLock = reflectionGetField(v, fieldName, v.javaClass) + + val writeVLock = object:Lock by origLock.writeLock(){ + override fun unlock() { + origLock.writeLock().unlock() + v.validate() + } + } + + val vLock = object:ReadWriteLock by origLock{ + override fun writeLock(): Lock { + return writeVLock + } + } + + reflectionSetField(v, vLock, fieldName, v.javaClass) + } +*/ + +} + +class TTTest{ + @Test fun _test_recur_delete(){ + val f = TT.tempDir(); + val f2 = File(f.path+"/aa/bb") + f2.mkdirs(); + val raf = RandomAccessFile(f2.path+"/aaa","rw"); + raf.writeInt(111) + raf.close() + + val f0 = File(f.path+".wal23432") + val raf2 = RandomAccessFile(f0,"rw"); + raf2.writeInt(111) + raf2.close() + + + TT.tempDelete(f) + assertFalse(f.exists()) + assertFalse(f0.exists()) + } + + @Test fun clone2(){ + val s = "djwqoidjioqwdjiqw 323423"; + assertEquals(s, TT.clone(s, Serializers.STRING)) + assertEquals(s, TT.cloneJavaSerialization(s)) + } + + @Test fun tempFileName_textets(){ + val f = TT.tempFile() + assertTrue(f.name,f.name.startsWith("mapdbTest_org.mapdb.TTTest-tempFileName_textets-")) + } +} + + +abstract class DBWordSpec(body: AbstractWordSpec.() -> Unit = {}) : WordSpec(body) { + + private val duration = + if(TT.shortTest()) Duration.ofSeconds(2) + else Duration.ofHours(12) + + override val defaultTestCaseConfig = TestCaseConfig( + timeout = duration) + +} \ No newline at end of file diff --git a/src/test/java/org/mapdb/TestTransactions.java b/src/test/java/org/mapdb/TestTransactions.java deleted file mode 100644 index b9de5a370..000000000 --- a/src/test/java/org/mapdb/TestTransactions.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.mapdb; - - -import org.junit.Test; - -import java.util.Map; - -/** - * - * @author Alan Franzoni - */ -public class TestTransactions { - - @Test - public void testSameCollectionInsertDifferentValuesInDifferentTransactions() throws Exception { - - TxMaker txMaker = DBMaker - .newMemoryDB() - .makeTxMaker(); - - DB txInit = txMaker.makeTx(); - Map mapInit = txInit.getTreeMap("testMap"); - - for (int i=0; i<1e4 ; i++ ) { - mapInit.put(i, String.format("%d", i)); - - } - txInit.commit(); - - DB tx1 = txMaker.makeTx(); - DB tx2 = txMaker.makeTx(); - - - Map map1 = tx1.getTreeMap("testMap"); - - map1.put(1, "asd"); - - tx1.commit(); - System.out.println("tx1 commit succeeded, map size after tx1 commits: " + txMaker.makeTx().getTreeMap("testMap").size()); - - Map map2 = tx2.getTreeMap("testMap"); - map2.put(10001, "somevalue"); - - // the following line throws a TxRollbackException - tx2.commit(); - txMaker.close(); - } - - @Test - public void testDifferentCollectionsInDifferentTransactions() throws Exception { - - TxMaker txMaker = DBMaker - .newMemoryDB() - .makeTxMaker(); - - DB txInit = txMaker.makeTx(); - Map mapInit = txInit.getTreeMap("testMap"); - Map otherMapInit = txInit.getTreeMap("otherMap"); - - for (int i=0; i<1e4 ; i++ ) { - mapInit.put(i, String.format("%d", i)); - otherMapInit.put(i, String.format("%d", i)); - - } - - txInit.commit(); - - DB tx1 = txMaker.makeTx(); - DB tx2 = txMaker.makeTx(); - - - Map map1 = tx1.getTreeMap("testMap"); - - map1.put(2, "asd"); - - tx1.commit(); - - Map map2 = tx2.getTreeMap("otherMap"); - map2.put(20, "somevalue"); - - // the following line throws a TxRollbackException - tx2.commit(); - txMaker.close(); - } - - @Test - public void testSameCollectionModifyDifferentValuesInDifferentTransactions() throws Exception { - - TxMaker txMaker = DBMaker - .newMemoryDB() - .makeTxMaker(); - - DB txInit = txMaker.makeTx(); - Map mapInit = txInit.getTreeMap("testMap"); - - for (int i=0; i<1e4 ; i++ ) { - mapInit.put(i, String.format("%d", i)); - - } - txInit.commit(); - - DB tx1 = txMaker.makeTx(); - DB tx2 = txMaker.makeTx(); - - - Map map1 = tx1.getTreeMap("testMap"); - - map1.put(1, "asd"); - - - tx1.commit(); - System.out.println("tx1 commit succeeded, map size after tx1 commits: " + txMaker.makeTx().getTreeMap("testMap").size()); - - Map map2 = tx2.getTreeMap("testMap"); - map2.put(100, "somevalue"); - - // the following line throws a TxRollbackException - tx2.commit(); - txMaker.close(); - } - - @Test - public void testTransactionsDoingNothing() throws Exception { - - TxMaker txMaker = DBMaker - .newMemoryDB() - .makeTxMaker(); - - DB txInit = txMaker.makeTx(); - Map mapInit = txInit.getTreeMap("testMap"); - - for (int i=0; i<1e4 ; i++ ) { - mapInit.put(i, String.format("%d", i)); - - } - txInit.commit(); - - - DB tx1 = txMaker.makeTx(); - DB tx2 = txMaker.makeTx(); - - - Map map1 = tx1.getTreeMap("testMap"); - - tx1.commit(); - - Map map2 = tx2.getTreeMap("testMap"); - - // the following line throws a TxRollbackException - tx2.commit(); - txMaker.close(); - } - -} \ No newline at end of file diff --git a/src/test/java/org/mapdb/TreeMapExtendTest.java b/src/test/java/org/mapdb/TreeMapExtendTest.java deleted file mode 100644 index 6a9a6285b..000000000 --- a/src/test/java/org/mapdb/TreeMapExtendTest.java +++ /dev/null @@ -1,13507 +0,0 @@ -package org.mapdb; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 - * - * http://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. - */ - -import junit.framework.TestCase; - -import java.io.Serializable; -import java.util.*; -import java.util.Map.Entry; - - -@SuppressWarnings({"rawtypes","unchecked"}) -public class TreeMapExtendTest extends TestCase { - - - // Regression for Harmony-1026 - public static class MockComparator> implements - Comparator, Serializable { - - public int compare(T o1, T o2) { - if (o1 == o2) { - return 0; - } - if (null == o1 || null == o2) { - return -1; - } - T c1 = o1; - T c2 = o2; - return c1.compareTo(c2); - } - } - - TreeMap tm; - - TreeMap tm_comparator; - - SortedMap subMap_default; - - SortedMap subMap_startExcluded_endExcluded; - - SortedMap subMap_startExcluded_endIncluded; - - SortedMap subMap_startIncluded_endExcluded; - - SortedMap subMap_startIncluded_endIncluded; - - SortedMap subMap_default_beforeStart_100; - - SortedMap subMap_default_afterEnd_109; - - NavigableMap navigableMap_startExcluded_endExcluded; - - NavigableMap navigableMap_startExcluded_endIncluded; - - NavigableMap navigableMap_startIncluded_endExcluded; - - NavigableMap navigableMap_startIncluded_endIncluded; - - SortedMap subMap_default_comparator; - - SortedMap subMap_startExcluded_endExcluded_comparator; - - SortedMap subMap_startExcluded_endIncluded_comparator; - - SortedMap subMap_startIncluded_endExcluded_comparator; - - SortedMap subMap_startIncluded_endIncluded_comparator; - - Object objArray[] = new Object[1000]; - - public void test_TreeMap_Constructor_Default() { - TreeMap treeMap = new TreeMap(); - assertTrue(treeMap.isEmpty()); - assertNull(treeMap.comparator()); - assertEquals(0, treeMap.size()); - - try { - treeMap.firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - assertNull(treeMap.firstEntry()); - - try { - treeMap.lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - assertNull(treeMap.lastEntry()); - - try { - treeMap.ceilingKey(1); - } catch (NoSuchElementException e) { - // Expected - } - assertNull(treeMap.ceilingEntry(1)); - - try { - treeMap.floorKey(1); - } catch (NoSuchElementException e) { - // Expected - } - assertNull(treeMap.floorEntry(1)); - assertNull(treeMap.lowerKey(1)); - assertNull(treeMap.lowerEntry(1)); - assertNull(treeMap.higherKey(1)); - assertNull(treeMap.higherEntry(1)); - assertFalse(treeMap.containsKey(1)); - assertFalse(treeMap.containsValue(1)); - assertNull(treeMap.get(1)); - - assertNull(treeMap.pollFirstEntry()); - assertNull(treeMap.pollLastEntry()); - assertEquals(0, treeMap.values().size()); - } - - public void test_TreeMap_Constructor_Comparator() { - MockComparator mockComparator = new MockComparator(); - TreeMap treeMap = new TreeMap(mockComparator); - - assertEquals(mockComparator, treeMap.comparator()); - } - - public void test_TreeMap_Constructor_Map() { - TreeMap treeMap = new TreeMap(tm); - assertEquals(tm.size(), treeMap.size()); - assertEquals(tm.firstKey(), treeMap.firstKey()); - assertEquals(tm.firstEntry(), treeMap.firstEntry()); - assertEquals(tm.lastKey(), treeMap.lastKey()); - assertEquals(tm.lastEntry(), treeMap.lastEntry()); - assertEquals(tm.keySet(), treeMap.keySet()); - - String key = new Integer(100).toString(); - assertEquals(tm.ceilingKey(key), treeMap.ceilingKey(key)); - assertEquals(tm.ceilingEntry(key), treeMap.ceilingEntry(key)); - assertEquals(tm.floorKey(key), treeMap.floorKey(key)); - assertEquals(tm.floorEntry(key), treeMap.floorEntry(key)); - assertEquals(tm.lowerKey(key), treeMap.lowerKey(key)); - assertEquals(tm.lowerEntry(key), treeMap.lowerEntry(key)); - assertEquals(tm.higherKey(key), treeMap.higherKey(key)); - assertEquals(tm.higherEntry(key), treeMap.higherEntry(key)); - assertEquals(tm.entrySet(), treeMap.entrySet()); - } - - public void test_TreeMap_Constructor_SortedMap() { - TreeMap treeMap = new TreeMap(subMap_default); - assertEquals(subMap_default.size(), treeMap.size()); - assertEquals(subMap_default.firstKey(), treeMap.firstKey()); - assertEquals(subMap_default.lastKey(), treeMap.lastKey()); - assertEquals(subMap_default.keySet(), treeMap.keySet()); - assertEquals(subMap_default.entrySet(), treeMap.entrySet()); - } - - public void test_TreeMap_clear() { - tm.clear(); - assertEquals(0, tm.size()); - } - - public void test_TreeMap_clone() { - TreeMap cloneTreeMap = (TreeMap) tm.clone(); - assertEquals(tm, cloneTreeMap); - } - - public void test_SubMap_Constructor() { - } - - public void test_SubMap_clear() { - subMap_default.clear(); - assertEquals(0, subMap_default.size()); - } - - public void test_SubMap_comparator() { - assertEquals(tm.comparator(), subMap_default.comparator()); - } - - public void test_SubMap_containsKey() { - String key = null; - for (int counter = 101; counter < 109; counter++) { - key = objArray[counter].toString(); - assertTrue("SubMap contains incorrect elements", subMap_default - .containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsKey(key)); - } - - // Check boundary - key = objArray[100].toString(); - assertTrue("SubMap contains incorrect elements", subMap_default - .containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsKey(key)); - - key = objArray[109].toString(); - assertFalse("SubMap contains incorrect elements", subMap_default - .containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsKey(key)); - - // With Comparator - for (int counter = 101; counter < 109; counter++) { - key = objArray[counter].toString(); - assertTrue("SubMap contains incorrect elements", - subMap_default_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded_comparator - .containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded_comparator - .containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded_comparator - .containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded_comparator - .containsKey(key)); - } - - // Check boundary - key = objArray[100].toString(); - assertTrue("SubMap contains incorrect elements", - subMap_default_comparator.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded_comparator.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded_comparator.containsKey(key)); - - key = objArray[109].toString(); - assertFalse("SubMap contains incorrect elements", - subMap_default_comparator.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded_comparator.containsKey(key)); - assertFalse("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded_comparator.containsKey(key)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded_comparator.containsKey(key)); - } - - public void test_SubMap_containsValue() { - Object value = null; - for (int counter = 101; counter < 109; counter++) { - value = objArray[counter]; - assertTrue("SubMap contains incorrect elements", subMap_default - .containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsValue(value)); - } - - // Check boundary - value = objArray[100]; - assertTrue("SubMap contains incorrect elements", subMap_default - .containsValue(value)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsValue(value)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsValue(value)); - - value = objArray[109]; - assertFalse("SubMap contains incorrect elements", subMap_default - .containsValue(value)); - assertFalse("SubMap contains incorrect elements", - subMap_startExcluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startExcluded_endIncluded.containsValue(value)); - assertFalse("SubMap contains incorrect elements", - subMap_startIncluded_endExcluded.containsValue(value)); - assertTrue("SubMap contains incorrect elements", - subMap_startIncluded_endIncluded.containsValue(value)); - - assertFalse(subMap_default.containsValue(null)); - - TreeMap tm_null = new TreeMap(); - tm_null.put("0", 1); - tm_null.put("1", null); - tm_null.put("2", 2); - SortedMap subMap = tm_null.subMap("0", "2"); - assertTrue(subMap.containsValue(null)); - - subMap.remove("1"); - assertFalse(subMap.containsValue(null)); - } - - public void test_SubMap_entrySet() { - Set entrySet = subMap_default.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(9, entrySet.size()); - - entrySet = subMap_startExcluded_endExcluded.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(8, entrySet.size()); - - entrySet = subMap_startExcluded_endIncluded.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(9, entrySet.size()); - - entrySet = subMap_startIncluded_endExcluded.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(9, entrySet.size()); - - entrySet = subMap_startIncluded_endIncluded.entrySet(); - assertFalse(entrySet.isEmpty()); - assertEquals(10, entrySet.size()); - } - - public void test_SubMap_firstKey() { - String firstKey1 = new Integer(100).toString(); - String firstKey2 = new Integer(101).toString(); - assertEquals(firstKey1, subMap_default.firstKey()); - assertEquals(firstKey2, subMap_startExcluded_endExcluded.firstKey()); - assertEquals(firstKey2, subMap_startExcluded_endIncluded.firstKey()); - assertEquals(firstKey1, subMap_startIncluded_endExcluded.firstKey()); - assertEquals(firstKey1, subMap_startIncluded_endIncluded.firstKey()); - - try { - subMap_default.subMap(firstKey1, firstKey1).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.subMap(firstKey2, firstKey2) - .firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.subMap(firstKey2, firstKey2) - .firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.subMap(firstKey1, firstKey1) - .firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.subMap(firstKey1, firstKey1) - .firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - // With Comparator - assertEquals(firstKey1, subMap_default_comparator.firstKey()); - assertEquals(firstKey2, subMap_startExcluded_endExcluded_comparator - .firstKey()); - assertEquals(firstKey2, subMap_startExcluded_endIncluded_comparator - .firstKey()); - assertEquals(firstKey1, subMap_startIncluded_endExcluded_comparator - .firstKey()); - assertEquals(firstKey1, subMap_startIncluded_endIncluded_comparator - .firstKey()); - - try { - subMap_default_comparator.subMap(firstKey1, firstKey1).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator.subMap(firstKey2, - firstKey2).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator.subMap(firstKey2, - firstKey2).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator.subMap(firstKey1, - firstKey1).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator.subMap(firstKey1, - firstKey1).firstKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - } - - public void test_SubMap_lastKey() { - String lastKey1 = new Integer(108).toString(); - String lastKey2 = new Integer(109).toString(); - assertEquals(lastKey1, subMap_default.lastKey()); - assertEquals(lastKey1, subMap_startExcluded_endExcluded.lastKey()); - assertEquals(lastKey2, subMap_startExcluded_endIncluded.lastKey()); - assertEquals(lastKey1, subMap_startIncluded_endExcluded.lastKey()); - assertEquals(lastKey2, subMap_startIncluded_endIncluded.lastKey()); - - try { - subMap_default.subMap(lastKey1, lastKey1).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.subMap(lastKey1, lastKey1) - .lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.subMap(lastKey2, lastKey2) - .lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.subMap(lastKey1, lastKey1) - .lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.subMap(lastKey2, lastKey2) - .lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - // With Comparator - assertEquals(lastKey1, subMap_default_comparator.lastKey()); - assertEquals(lastKey1, subMap_startExcluded_endExcluded_comparator - .lastKey()); - assertEquals(lastKey2, subMap_startExcluded_endIncluded_comparator - .lastKey()); - assertEquals(lastKey1, subMap_startIncluded_endExcluded_comparator - .lastKey()); - assertEquals(lastKey2, subMap_startIncluded_endIncluded_comparator - .lastKey()); - - try { - subMap_default_comparator.subMap(lastKey1, lastKey1).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator.subMap(lastKey1, - lastKey1).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator.subMap(lastKey2, - lastKey2).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator.subMap(lastKey1, - lastKey1).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator.subMap(lastKey2, - lastKey2).lastKey(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - public void test_SubMap_get() { - // left boundary - Integer value = new Integer(100); - assertEquals(value, subMap_default.get(value.toString())); - assertEquals(null, subMap_startExcluded_endExcluded.get(value - .toString())); - assertEquals(null, subMap_startExcluded_endIncluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endIncluded.get(value - .toString())); - - // normal value - value = new Integer(105); - assertEquals(value, subMap_default.get(value.toString())); - assertEquals(value, subMap_startExcluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startExcluded_endIncluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endIncluded.get(value - .toString())); - - // right boundary - value = new Integer(109); - assertEquals(null, subMap_default.get(value.toString())); - assertEquals(null, subMap_startExcluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startExcluded_endIncluded.get(value - .toString())); - assertEquals(null, subMap_startIncluded_endExcluded.get(value - .toString())); - assertEquals(value, subMap_startIncluded_endIncluded.get(value - .toString())); - - // With Comparator to test inInRange - // left boundary - value = new Integer(100); - assertEquals(value, subMap_default_comparator.get(value.toString())); - - // normal value - value = new Integer(105); - assertEquals(value, subMap_default_comparator.get(value.toString())); - - // right boundary - value = new Integer(109); - assertEquals(null, subMap_default_comparator.get(value.toString())); - } - - public void test_SubMap_headMap() { - String endKey = new Integer(99).toString(); - try { - subMap_default.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - SortedMap headMap = null; - endKey = new Integer(100).toString(); - headMap = subMap_default.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startExcluded_endExcluded.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startExcluded_endIncluded.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startIncluded_endExcluded.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startIncluded_endIncluded.headMap(endKey); - assertEquals(0, headMap.size()); - - for (int i = 0, j = 101; i < 8; i++) { - endKey = new Integer(i + j).toString(); - headMap = subMap_default.headMap(endKey); - assertEquals(i + 1, headMap.size()); - - headMap = subMap_startExcluded_endExcluded.headMap(endKey); - assertEquals(i, headMap.size()); - - headMap = subMap_startExcluded_endIncluded.headMap(endKey); - assertEquals(i, headMap.size()); - - headMap = subMap_startIncluded_endExcluded.headMap(endKey); - assertEquals(i + 1, headMap.size()); - - headMap = subMap_startIncluded_endIncluded.headMap(endKey); - assertEquals(i + 1, headMap.size()); - } - - endKey = new Integer(109).toString(); - headMap = subMap_default.headMap(endKey); - assertEquals(9, headMap.size()); - - headMap = subMap_startExcluded_endExcluded.headMap(endKey); - assertEquals(8, headMap.size()); - - headMap = subMap_startExcluded_endIncluded.headMap(endKey); - assertEquals(8, headMap.size()); - - headMap = subMap_startIncluded_endExcluded.headMap(endKey); - assertEquals(9, headMap.size()); - - headMap = subMap_startIncluded_endIncluded.headMap(endKey); - assertEquals(9, headMap.size()); - - endKey = new Integer(110).toString(); - try { - subMap_default.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // With Comparator - endKey = new Integer(99).toString(); - try { - subMap_default_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - headMap = null; - endKey = new Integer(100).toString(); - headMap = subMap_default_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startExcluded_endExcluded_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startExcluded_endIncluded_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startIncluded_endExcluded_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - headMap = subMap_startIncluded_endIncluded_comparator.headMap(endKey); - assertEquals(0, headMap.size()); - - for (int i = 0, j = 101; i < 8; i++) { - endKey = new Integer(i + j).toString(); - headMap = subMap_default_comparator.headMap(endKey); - assertEquals(i + 1, headMap.size()); - - headMap = subMap_startExcluded_endExcluded_comparator - .headMap(endKey); - assertEquals(i, headMap.size()); - - headMap = subMap_startExcluded_endIncluded_comparator - .headMap(endKey); - assertEquals(i, headMap.size()); - - headMap = subMap_startIncluded_endExcluded_comparator - .headMap(endKey); - assertEquals(i + 1, headMap.size()); - - headMap = subMap_startIncluded_endIncluded_comparator - .headMap(endKey); - assertEquals(i + 1, headMap.size()); - } - - endKey = new Integer(108).toString(); - headMap = subMap_default_comparator.headMap(endKey); - assertEquals(8, headMap.size()); - - headMap = subMap_startExcluded_endExcluded_comparator.headMap(endKey); - assertEquals(7, headMap.size()); - - headMap = subMap_startExcluded_endIncluded_comparator.headMap(endKey); - assertEquals(7, headMap.size()); - - headMap = subMap_startIncluded_endExcluded_comparator.headMap(endKey); - assertEquals(8, headMap.size()); - - headMap = subMap_startIncluded_endIncluded_comparator.headMap(endKey); - assertEquals(8, headMap.size()); - - endKey = new Integer(110).toString(); - try { - subMap_default_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator.headMap(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } - - public void test_SubMap_isEmpty() { - assertFalse(subMap_default.isEmpty()); - assertFalse(subMap_startExcluded_endExcluded.isEmpty()); - assertFalse(subMap_startExcluded_endIncluded.isEmpty()); - assertFalse(subMap_startIncluded_endExcluded.isEmpty()); - assertFalse(subMap_startIncluded_endIncluded.isEmpty()); - - Object startKey = new Integer(100); - Object endKey = startKey; - SortedMap subMap = tm.subMap(startKey.toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - subMap = subMap_default.subMap(startKey.toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - subMap = subMap_startIncluded_endExcluded.subMap(startKey.toString(), - endKey.toString()); - assertTrue(subMap.isEmpty()); - subMap = subMap_startIncluded_endIncluded.subMap(startKey.toString(), - endKey.toString()); - assertTrue(subMap.isEmpty()); - - for (int i = 0, j = 101; i < 8; i++) { - startKey = i + j; - endKey = startKey; - - subMap = subMap_default.subMap(startKey.toString(), endKey - .toString()); - assertTrue(subMap.isEmpty()); - - subMap = subMap_startExcluded_endExcluded.subMap(startKey - .toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - - subMap = subMap_startExcluded_endIncluded.subMap(startKey - .toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - - subMap = subMap_startIncluded_endExcluded.subMap(startKey - .toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - - subMap = subMap_startIncluded_endIncluded.subMap(startKey - .toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - } - - for (int i = 0, j = 101; i < 5; i++) { - startKey = i + j; - endKey = i + j + 4; - - subMap = subMap_default.subMap(startKey.toString(), endKey - .toString()); - assertFalse(subMap.isEmpty()); - - subMap = subMap_startExcluded_endExcluded.subMap(startKey - .toString(), endKey.toString()); - assertFalse(subMap.isEmpty()); - - subMap = subMap_startExcluded_endIncluded.subMap(startKey - .toString(), endKey.toString()); - assertFalse(subMap.isEmpty()); - - subMap = subMap_startIncluded_endExcluded.subMap(startKey - .toString(), endKey.toString()); - assertFalse(subMap.isEmpty()); - - subMap = subMap_startIncluded_endIncluded.subMap(startKey - .toString(), endKey.toString()); - assertFalse(subMap.isEmpty()); - } - - startKey = new Integer(109).toString(); - endKey = startKey; - subMap = tm.subMap(startKey.toString(), endKey.toString()); - assertTrue(subMap.isEmpty()); - subMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey); - assertTrue(subMap.isEmpty()); - subMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey); - assertTrue(subMap.isEmpty()); - - } - - public void test_SubMap_keySet() { - Set keySet = subMap_default.keySet(); - assertFalse(keySet.isEmpty()); - assertEquals(9, keySet.size()); - - keySet = subMap_startExcluded_endExcluded.entrySet(); - assertFalse(keySet.isEmpty()); - assertEquals(8, keySet.size()); - - keySet = subMap_startExcluded_endIncluded.entrySet(); - assertFalse(keySet.isEmpty()); - assertEquals(9, keySet.size()); - - keySet = subMap_startIncluded_endExcluded.entrySet(); - assertFalse(keySet.isEmpty()); - assertEquals(9, keySet.size()); - - keySet = subMap_startIncluded_endIncluded.entrySet(); - assertFalse(keySet.isEmpty()); - assertEquals(10, keySet.size()); - } - - public void test_SubMap_put() { - Integer value = new Integer(100); - int addValue = 5; - - subMap_default.put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_default.get(value.toString())); - - try { - subMap_startExcluded_endExcluded.put(value.toString(), value - + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.put(value.toString(), value - + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subMap_startIncluded_endExcluded - .put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_startIncluded_endExcluded - .get(value.toString())); - - subMap_startIncluded_endIncluded - .put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_startIncluded_endIncluded - .get(value.toString())); - - value = new Integer(109); - try { - subMap_default.put(value.toString(), value + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.put(value.toString(), value - + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subMap_startExcluded_endIncluded - .put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_startExcluded_endIncluded - .get(value.toString())); - - try { - subMap_startIncluded_endExcluded.put(value.toString(), value - + addValue); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subMap_startIncluded_endIncluded - .put(value.toString(), value + addValue); - assertEquals(value + addValue, subMap_startIncluded_endIncluded - .get(value.toString())); - } - - public void test_SubMap_remove() { - Integer value = new Integer(100); - - subMap_default.remove(value.toString()); - assertNull(subMap_default.get(value.toString())); - - subMap_startExcluded_endExcluded.remove(value.toString()); - assertNull(subMap_startExcluded_endExcluded.get(value.toString())); - - subMap_startExcluded_endIncluded.remove(value.toString()); - assertNull(subMap_startExcluded_endIncluded.get(value.toString())); - - subMap_startIncluded_endExcluded.remove(value.toString()); - assertNull(subMap_startIncluded_endExcluded.get(value.toString())); - - subMap_startIncluded_endIncluded.remove(value.toString()); - assertNull(subMap_startIncluded_endIncluded.get(value.toString())); - - value = new Integer(109); - subMap_default.remove(value.toString()); - assertNull(subMap_default.get(value.toString())); - - subMap_startExcluded_endExcluded.remove(value.toString()); - assertNull(subMap_startExcluded_endExcluded.get(value.toString())); - - subMap_startExcluded_endIncluded.remove(value.toString()); - assertNull(subMap_startExcluded_endIncluded.get(value.toString())); - - subMap_startIncluded_endExcluded.remove(value.toString()); - assertNull(subMap_startIncluded_endExcluded.get(value.toString())); - - subMap_startIncluded_endIncluded.remove(value.toString()); - assertNull(subMap_startIncluded_endIncluded.get(value.toString())); - } - - public void test_SubMap_subMap_NoComparator() { - String startKey = new Integer[100].toString(); - String endKey = new Integer[100].toString(); - try { - subMap_default.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - SortedMap subSubMap = null; - for (int i = 101; i < 109; i++) { - startKey = new Integer(i).toString(); - endKey = startKey; - - subSubMap = subMap_default.subMap(startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded.subMap(startKey, - endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, - endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded.subMap(startKey, - endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, - endKey); - assertEquals(0, subSubMap.size()); - } - - for (int i = 101, j = 5; i < 105; i++) { - startKey = new Integer(i).toString(); - endKey = new Integer(i + j).toString(); - - subSubMap = subMap_default.subMap(startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded.subMap(startKey, - endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, - endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded.subMap(startKey, - endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, - endKey); - assertEquals(j, subSubMap.size()); - } - - startKey = new Integer(108).toString(); - endKey = new Integer(109).toString(); - - subSubMap = subMap_default.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - startKey = new Integer(109).toString(); - endKey = new Integer(109).toString(); - - try { - subMap_default.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subSubMap = subMap_startExcluded_endIncluded.subMap(startKey, endKey); - assertEquals(0, subSubMap.size()); - - try { - subMap_startIncluded_endExcluded.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subSubMap = subMap_startIncluded_endIncluded.subMap(startKey, endKey); - assertEquals(0, subSubMap.size()); - } - - public void test_SubMap_subMap_Comparator() { - String startKey = new Integer[100].toString(); - String endKey = new Integer[100].toString(); - try { - subMap_default_comparator.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - SortedMap subSubMap = null; - for (int i = 101; i < 109; i++) { - startKey = new Integer(i).toString(); - endKey = startKey; - - subSubMap = subMap_default_comparator.subMap(startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - } - - for (int i = 101, j = 5; i < 105; i++) { - startKey = new Integer(i).toString(); - endKey = new Integer(i + j).toString(); - - subSubMap = subMap_default_comparator.subMap(startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(j, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(j, subSubMap.size()); - } - - startKey = new Integer(108).toString(); - endKey = new Integer(109).toString(); - - subSubMap = subMap_default_comparator.subMap(startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startExcluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startExcluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startIncluded_endExcluded_comparator.subMap( - startKey, endKey); - assertEquals(1, subSubMap.size()); - - subSubMap = subMap_startIncluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(1, subSubMap.size()); - - startKey = new Integer(109).toString(); - endKey = new Integer(109).toString(); - - try { - subMap_default_comparator.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subSubMap = subMap_startExcluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - - try { - subMap_startIncluded_endExcluded_comparator - .subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - subSubMap = subMap_startIncluded_endIncluded_comparator.subMap( - startKey, endKey); - assertEquals(0, subSubMap.size()); - } - - public void test_SubMap_tailMap() { - String startKey = new Integer(99).toString(); - try { - subMap_default.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startIncluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - SortedMap tailMap = null; - - startKey = new Integer(100).toString(); - tailMap = subMap_default.tailMap(startKey); - assertEquals(9, tailMap.size()); - - try { - subMap_startExcluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - tailMap = subMap_startIncluded_endExcluded.tailMap(startKey); - assertEquals(9, tailMap.size()); - - tailMap = subMap_startIncluded_endIncluded.tailMap(startKey); - assertEquals(10, tailMap.size()); - - for (int i = 0, j = 101, end = 8; i < end; i++) { - startKey = new Integer(i + j).toString(); - tailMap = subMap_default.tailMap(startKey); - assertEquals(end - i, tailMap.size()); - - tailMap = subMap_startExcluded_endExcluded.tailMap(startKey); - assertEquals(end - i, tailMap.size()); - - tailMap = subMap_startExcluded_endIncluded.tailMap(startKey); - assertEquals(end - i + 1, tailMap.size()); - - tailMap = subMap_startIncluded_endExcluded.tailMap(startKey); - assertEquals(end - i, tailMap.size()); - - tailMap = subMap_startIncluded_endIncluded.tailMap(startKey); - assertEquals(end - i + 1, tailMap.size()); - } - - startKey = new Integer(109).toString(); - try { - subMap_default.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - subMap_startExcluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - tailMap = subMap_startExcluded_endIncluded.tailMap(startKey); - assertEquals(1, tailMap.size()); - - try { - subMap_startIncluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - tailMap = subMap_startIncluded_endIncluded.tailMap(startKey); - assertEquals(1, tailMap.size()); - - startKey = new Integer(110).toString(); - try { - subMap_default.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - subMap_startExcluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - subMap_startExcluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - subMap_startIncluded_endExcluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - subMap_startIncluded_endIncluded.tailMap(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } - - public void test_SubMap_values() { - Collection values = subMap_default.values(); - - assertFalse(values.isEmpty()); - assertTrue(values.contains(100)); - for (int i = 101; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertFalse(values.contains(109)); - - values = subMap_startExcluded_endExcluded.values(); - assertFalse(values.isEmpty()); - assertFalse(values.contains(100)); - for (int i = 101; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertFalse(values.contains(109)); - - values = subMap_startExcluded_endIncluded.values(); - assertFalse(values.isEmpty()); - assertFalse(values.contains(100)); - for (int i = 101; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertTrue(values.contains(109)); - - values = subMap_startIncluded_endExcluded.values(); - assertFalse(values.isEmpty()); - assertTrue(values.contains(100)); - for (int i = 101; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertFalse(values.contains(109)); - - values = subMap_startIncluded_endIncluded.values(); - assertFalse(values.isEmpty()); - assertTrue(values.contains(100)); - for (int i = 100; i < 109; i++) { - assertTrue(values.contains(i)); - } - assertTrue(values.contains(109)); - } - - public void test_SubMap_size() { - assertEquals(9, subMap_default.size()); - assertEquals(8, subMap_startExcluded_endExcluded.size()); - assertEquals(9, subMap_startExcluded_endIncluded.size()); - assertEquals(9, subMap_startIncluded_endExcluded.size()); - assertEquals(10, subMap_startIncluded_endIncluded.size()); - - assertEquals(9, subMap_default_comparator.size()); - assertEquals(8, subMap_startExcluded_endExcluded_comparator.size()); - assertEquals(9, subMap_startExcluded_endIncluded_comparator.size()); - assertEquals(9, subMap_startIncluded_endExcluded_comparator.size()); - assertEquals(10, subMap_startIncluded_endIncluded_comparator.size()); - } - - public void test_SubMap_readObject() throws Exception { - // SerializationTest.verifySelf(subMap_default); - // SerializationTest.verifySelf(subMap_startExcluded_endExcluded); - // SerializationTest.verifySelf(subMap_startExcluded_endIncluded); - // SerializationTest.verifySelf(subMap_startIncluded_endExcluded); - // SerializationTest.verifySelf(subMap_startIncluded_endIncluded); - } - - public void test_AscendingSubMap_ceilingEntry() { - String key = new Integer(99).toString(); - assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key)); - assertNull(navigableMap_startExcluded_endIncluded.ceilingEntry(key)); - assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key)); - assertNull(navigableMap_startIncluded_endIncluded.ceilingEntry(key)); - - key = new Integer(100).toString(); - assertEquals(101, navigableMap_startExcluded_endExcluded.ceilingEntry( - key).getValue()); - assertEquals(101, navigableMap_startExcluded_endIncluded.ceilingEntry( - key).getValue()); - assertEquals(100, navigableMap_startIncluded_endExcluded.ceilingEntry( - key).getValue()); - assertEquals(100, navigableMap_startIncluded_endIncluded.ceilingEntry( - key).getValue()); - - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, navigableMap_startExcluded_endExcluded - .ceilingEntry(key).getValue()); - assertEquals(i, navigableMap_startExcluded_endIncluded - .ceilingEntry(key).getValue()); - assertEquals(i, navigableMap_startIncluded_endExcluded - .ceilingEntry(key).getValue()); - assertEquals(i, navigableMap_startIncluded_endIncluded - .ceilingEntry(key).getValue()); - - } - - key = new Integer(109).toString(); - assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key)); - assertEquals(109, navigableMap_startExcluded_endIncluded.ceilingEntry( - key).getValue()); - assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key)); - assertEquals(109, navigableMap_startIncluded_endIncluded.ceilingEntry( - key).getValue()); - - key = new Integer(110).toString(); - assertNull(navigableMap_startExcluded_endExcluded.ceilingEntry(key)); - assertNull(navigableMap_startExcluded_endIncluded.ceilingEntry(key)); - assertNull(navigableMap_startIncluded_endExcluded.ceilingEntry(key)); - assertNull(navigableMap_startIncluded_endIncluded.ceilingEntry(key)); - } - - public void test_AscendingSubMap_descendingMap() { - NavigableMap descendingMap = navigableMap_startExcluded_endExcluded - .descendingMap(); - assertEquals(navigableMap_startExcluded_endExcluded.size(), - descendingMap.size()); - assertNotNull(descendingMap.comparator()); - - assertEquals(navigableMap_startExcluded_endExcluded.firstKey(), - descendingMap.lastKey()); - assertEquals(navigableMap_startExcluded_endExcluded.firstEntry(), - descendingMap.lastEntry()); - - assertEquals(navigableMap_startExcluded_endExcluded.lastKey(), - descendingMap.firstKey()); - assertEquals(navigableMap_startExcluded_endExcluded.lastEntry(), - descendingMap.firstEntry()); - - descendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - assertEquals(navigableMap_startExcluded_endIncluded.size(), - descendingMap.size()); - assertNotNull(descendingMap.comparator()); - - assertEquals(navigableMap_startExcluded_endIncluded.firstKey(), - descendingMap.lastKey()); - assertEquals(navigableMap_startExcluded_endIncluded.firstEntry(), - descendingMap.lastEntry()); - - assertEquals(navigableMap_startExcluded_endIncluded.lastKey(), - descendingMap.firstKey()); - assertEquals(navigableMap_startExcluded_endIncluded.lastEntry(), - descendingMap.firstEntry()); - - descendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - assertEquals(navigableMap_startIncluded_endExcluded.size(), - descendingMap.size()); - assertNotNull(descendingMap.comparator()); - - assertEquals(navigableMap_startIncluded_endExcluded.firstKey(), - descendingMap.lastKey()); - assertEquals(navigableMap_startIncluded_endExcluded.firstEntry(), - descendingMap.lastEntry()); - - assertEquals(navigableMap_startIncluded_endExcluded.lastKey(), - descendingMap.firstKey()); - assertEquals(navigableMap_startIncluded_endExcluded.lastEntry(), - descendingMap.firstEntry()); - - descendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - assertEquals(navigableMap_startIncluded_endIncluded.size(), - descendingMap.size()); - assertNotNull(descendingMap.comparator()); - - assertEquals(navigableMap_startIncluded_endIncluded.firstKey(), - descendingMap.lastKey()); - assertEquals(navigableMap_startIncluded_endIncluded.firstEntry(), - descendingMap.lastEntry()); - - assertEquals(navigableMap_startIncluded_endIncluded.lastKey(), - descendingMap.firstKey()); - assertEquals(navigableMap_startIncluded_endIncluded.lastEntry(), - descendingMap.firstEntry()); - } - - public void test_AscendingSubMap_floorEntry() { - String key = new Integer(99).toString(); - assertEquals(108, navigableMap_startExcluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startExcluded_endIncluded - .floorEntry(key).getValue()); - assertEquals(108, navigableMap_startIncluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startIncluded_endIncluded - .floorEntry(key).getValue()); - - key = new Integer(100).toString(); - assertNull(navigableMap_startExcluded_endExcluded.floorEntry(key)); - assertNull(navigableMap_startExcluded_endIncluded.floorEntry(key)); - assertEquals(100, navigableMap_startIncluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(100, navigableMap_startIncluded_endIncluded - .floorEntry(key).getValue()); - - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, navigableMap_startExcluded_endExcluded.floorEntry( - key).getValue()); - assertEquals(i, navigableMap_startExcluded_endIncluded.floorEntry( - key).getValue()); - assertEquals(i, navigableMap_startIncluded_endExcluded.floorEntry( - key).getValue()); - assertEquals(i, navigableMap_startIncluded_endIncluded.floorEntry( - key).getValue()); - - } - - key = new Integer(109).toString(); - assertEquals(108, navigableMap_startExcluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startExcluded_endIncluded - .floorEntry(key).getValue()); - assertEquals(108, navigableMap_startIncluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startIncluded_endIncluded - .floorEntry(key).getValue()); - - key = new Integer(110).toString(); - assertEquals(108, navigableMap_startExcluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startExcluded_endIncluded - .floorEntry(key).getValue()); - assertEquals(108, navigableMap_startIncluded_endExcluded - .floorEntry(key).getValue()); - assertEquals(109, navigableMap_startIncluded_endIncluded - .floorEntry(key).getValue()); - } - - public void test_AscendingSubMap_pollFirstEntry() { - assertEquals(101, navigableMap_startExcluded_endExcluded - .pollFirstEntry().getValue()); - assertEquals(102, navigableMap_startExcluded_endIncluded - .pollFirstEntry().getValue()); - assertEquals(100, navigableMap_startIncluded_endExcluded - .pollFirstEntry().getValue()); - assertEquals(103, navigableMap_startIncluded_endIncluded - .pollFirstEntry().getValue()); - } - - public void test_AscendingSubMap_pollLastEntry() { - assertEquals(108, navigableMap_startExcluded_endExcluded - .pollLastEntry().getValue()); - assertEquals(109, navigableMap_startExcluded_endIncluded - .pollLastEntry().getValue()); - assertEquals(107, navigableMap_startIncluded_endExcluded - .pollLastEntry().getValue()); - assertEquals(106, navigableMap_startIncluded_endIncluded - .pollLastEntry().getValue()); - } - - public void test_AscendingSubMap_entrySet() { - assertEquals(8, navigableMap_startExcluded_endExcluded.entrySet() - .size()); - assertEquals(9, navigableMap_startExcluded_endIncluded.entrySet() - .size()); - assertEquals(9, navigableMap_startIncluded_endExcluded.entrySet() - .size()); - assertEquals(10, navigableMap_startIncluded_endIncluded.entrySet() - .size()); - } - - public void test_AscendingSubMap_subMap() { - Set entrySet; - Entry startEntry, endEntry; - int startIndex, endIndex; - SortedMap subMap; - Iterator subMapSetIterator; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - Iterator startIterator = entrySet.iterator(); - while (startIterator.hasNext()) { - startEntry = (Entry) startIterator.next(); - startIndex = (Integer) startEntry.getValue(); - Iterator endIterator = entrySet.iterator(); - while (endIterator.hasNext()) { - endEntry = (Entry) endIterator.next(); - endIndex = (Integer) endEntry.getValue(); - - if (startIndex > endIndex) { - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), endEntry.getKey()); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), false, endEntry.getKey(), - false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), false, endEntry.getKey(), - true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), true, endEntry.getKey(), - false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), true, endEntry.getKey(), - true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subMap = navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), endEntry.getKey()); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex; index < endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - - subMap = navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), false, endEntry.getKey(), - false); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex + 1; index < endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - - subMap = navigableMap_startExcluded_endExcluded - .subMap(startEntry.getKey(), false, endEntry - .getKey(), true); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex + 1; index < endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - - subMap = navigableMap_startExcluded_endExcluded - .subMap(startEntry.getKey(), true, endEntry - .getKey(), false); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex; index < endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - - subMap = navigableMap_startExcluded_endExcluded.subMap( - startEntry.getKey(), true, endEntry.getKey(), true); - subMapSetIterator = subMap.entrySet().iterator(); - for (int index = startIndex; index <= endIndex; index++) { - assertEquals(index, ((Entry) subMapSetIterator.next()) - .getValue()); - } - } - } - } - } - - public void test_DescendingSubMap_ceilingEntry() { - NavigableMap decendingMap = tm.descendingMap(); - String key = new Integer(-1).toString(); - assertNull(decendingMap.ceilingEntry(key)); - for (int i = 0; i < objArray.length; i++) { - key = objArray[i].toString(); - assertEquals(objArray[i], decendingMap.ceilingEntry(key).getValue()); - } - key = new Integer(1000).toString(); - assertEquals(100, decendingMap.ceilingEntry(key).getValue()); - key = new Integer(1001).toString(); - assertEquals(100, decendingMap.ceilingEntry(key).getValue()); - - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - key = new Integer(100).toString(); - assertNull(decendingMap.ceilingEntry(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.ceilingEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(108, decendingMap.ceilingEntry(key).getValue()); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - key = new Integer(100).toString(); - assertNull(decendingMap.ceilingEntry(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.ceilingEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(109, decendingMap.ceilingEntry(key).getValue()); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - key = new Integer(100).toString(); - assertEquals(100, decendingMap.ceilingEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.ceilingEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(108, decendingMap.ceilingEntry(key).getValue()); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - key = new Integer(100).toString(); - assertEquals(100, decendingMap.ceilingEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.ceilingEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(109, decendingMap.ceilingEntry(key).getValue()); - - // With Comparator - decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .descendingMap(); - key = new Integer(100).toString(); - assertNull(decendingMap.ceilingEntry(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.ceilingEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(108, decendingMap.ceilingEntry(key).getValue()); - - decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .descendingMap(); - key = new Integer(100).toString(); - assertNull(decendingMap.ceilingEntry(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.ceilingEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(109, decendingMap.ceilingEntry(key).getValue()); - - decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded_comparator) - .descendingMap(); - key = new Integer(100).toString(); - assertEquals(100, decendingMap.ceilingEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.ceilingEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(108, decendingMap.ceilingEntry(key).getValue()); - - decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded_comparator) - .descendingMap(); - key = new Integer(100).toString(); - assertEquals(100, decendingMap.ceilingEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.ceilingEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(109, decendingMap.ceilingEntry(key).getValue()); - } - - public void test_DescendingSubMap_descendingMap() { - NavigableMap decendingMap = tm.descendingMap(); - NavigableMap decendingDecendingMap = decendingMap.descendingMap(); - assertEquals(decendingMap, decendingDecendingMap); - - NavigableMap decendingMapHeadMap = decendingMap.headMap( - new Integer(990).toString(), false); - NavigableMap decendingDecendingHeadMap = decendingMapHeadMap - .descendingMap(); - assertNotNull(decendingMapHeadMap); - assertNotNull(decendingDecendingHeadMap); - assertEquals(decendingMapHeadMap, decendingDecendingHeadMap); - - NavigableMap decendingMapTailMap = decendingMap.tailMap( - new Integer(990).toString(), false); - NavigableMap decendingDecendingTailMap = decendingMapTailMap - .descendingMap(); - assertNotNull(decendingMapTailMap); - assertNotNull(decendingDecendingTailMap); - // assertEquals(decendingMapTailMap,decendingDecendingTailMap); - - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - decendingDecendingMap = decendingMap.descendingMap(); - assertEquals(decendingMap, decendingDecendingMap); - - decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(), - false); - decendingDecendingHeadMap = decendingMapHeadMap.descendingMap(); - assertEquals(decendingMapHeadMap, decendingDecendingHeadMap); - - decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(), - false); - decendingDecendingTailMap = decendingMapTailMap.descendingMap(); - assertEquals(decendingMapTailMap, decendingDecendingTailMap); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - decendingDecendingMap = decendingMap.descendingMap(); - assertEquals(decendingMap, decendingDecendingMap); - - decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(), - false); - decendingDecendingHeadMap = decendingMapHeadMap.descendingMap(); - assertEquals(decendingMapHeadMap, decendingDecendingHeadMap); - - decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(), - false); - decendingDecendingTailMap = decendingMapTailMap.descendingMap(); - assertEquals(decendingMapTailMap, decendingDecendingTailMap); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - decendingDecendingMap = decendingMap.descendingMap(); - assertEquals(decendingMap, decendingDecendingMap); - - decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(), - false); - decendingDecendingHeadMap = decendingMapHeadMap.descendingMap(); - assertEquals(decendingMapHeadMap, decendingDecendingHeadMap); - - decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(), - false); - decendingDecendingTailMap = decendingMapTailMap.descendingMap(); - assertEquals(decendingMapTailMap, decendingDecendingTailMap); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - decendingDecendingMap = decendingMap.descendingMap(); - assertEquals(decendingMap, decendingDecendingMap); - - decendingMapHeadMap = decendingMap.headMap(new Integer(104).toString(), - false); - decendingDecendingHeadMap = decendingMapHeadMap.descendingMap(); - assertEquals(decendingMapHeadMap, decendingDecendingHeadMap); - - decendingMapTailMap = decendingMap.tailMap(new Integer(104).toString(), - false); - decendingDecendingTailMap = decendingMapTailMap.descendingMap(); - assertEquals(decendingMapTailMap, decendingDecendingTailMap); - } - - public void test_DescendingSubMap_firstEntry() { - NavigableMap decendingMap = tm.descendingMap(); - assertEquals(999, decendingMap.firstEntry().getValue()); - - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - assertEquals(108, decendingMap.firstEntry().getValue()); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - assertEquals(109, decendingMap.firstEntry().getValue()); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - assertEquals(108, decendingMap.firstEntry().getValue()); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - assertEquals(109, decendingMap.firstEntry().getValue()); - } - - public void test_DescendingSubMap_floorEntry() { - NavigableMap decendingMap = tm.descendingMap(); - String key = new Integer(-1).toString(); - assertEquals(0, decendingMap.floorEntry(key).getValue()); - for (int i = 0; i < objArray.length; i++) { - key = objArray[i].toString(); - assertEquals(objArray[i], decendingMap.floorEntry(key).getValue()); - } - key = new Integer(1000).toString(); - assertEquals(101, decendingMap.floorEntry(key).getValue()); - key = new Integer(1001).toString(); - assertEquals(101, decendingMap.floorEntry(key).getValue()); - - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - key = new Integer(100).toString(); - assertEquals(101, decendingMap.floorEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.floorEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertNull(decendingMap.floorEntry(key)); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - key = new Integer(100).toString(); - assertEquals(101, decendingMap.floorEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.floorEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(109, decendingMap.floorEntry(key).getValue()); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - key = new Integer(100).toString(); - assertEquals(100, decendingMap.floorEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.floorEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertNull(decendingMap.floorEntry(key)); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - key = new Integer(100).toString(); - assertEquals(100, decendingMap.floorEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.floorEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(109, decendingMap.floorEntry(key).getValue()); - - // With Comparator - decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .descendingMap(); - key = new Integer(100).toString(); - assertEquals(101, decendingMap.floorEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.floorEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertNull(decendingMap.floorEntry(key)); - - decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .descendingMap(); - key = new Integer(100).toString(); - assertEquals(101, decendingMap.floorEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.floorEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(109, decendingMap.floorEntry(key).getValue()); - - decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded_comparator) - .descendingMap(); - key = new Integer(100).toString(); - assertEquals(100, decendingMap.floorEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.floorEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertNull(decendingMap.floorEntry(key)); - - decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded_comparator) - .descendingMap(); - key = new Integer(100).toString(); - assertEquals(100, decendingMap.floorEntry(key).getValue()); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertEquals(i, decendingMap.floorEntry(key).getValue()); - } - key = new Integer(109).toString(); - assertEquals(109, decendingMap.floorEntry(key).getValue()); - } - - public void test_DescendingSubMap_lastEntry() { - NavigableMap decendingMap = tm.descendingMap(); - assertEquals(0, decendingMap.lastEntry().getValue()); - - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - assertEquals(101, decendingMap.lastEntry().getValue()); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - assertEquals(101, decendingMap.lastEntry().getValue()); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - assertEquals(100, decendingMap.lastEntry().getValue()); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - assertEquals(100, decendingMap.lastEntry().getValue()); - } - - public void test_DescendingSubMap_higherEntry() { - NavigableMap decendingMap; - NavigableMap decendingTailMap; - Integer value; - Entry entry; - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - value = new Integer(101); - assertNull(decendingMap.higherEntry(value.toString())); - - for (int i = 108; i > 101; i--) { - value = new Integer(i); - entry = decendingMap.higherEntry(value.toString()); - assertEquals(value - 1, entry.getValue()); - } - - value = new Integer(109); - entry = decendingMap.higherEntry(value.toString()); - assertEquals(108, entry.getValue()); - - decendingTailMap = decendingMap.tailMap(new Integer(104).toString(), - false); - value = new Integer(109); - entry = decendingTailMap.higherEntry(value.toString()); - assertEquals(103, entry.getValue()); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - value = new Integer(100); - assertNull(decendingMap.higherEntry(value.toString())); - - for (int i = 108; i > 100; i--) { - value = new Integer(i); - entry = decendingMap.higherEntry(value.toString()); - assertEquals(value - 1, entry.getValue()); - } - - value = new Integer(109); - entry = decendingMap.higherEntry(value.toString()); - assertEquals(108, entry.getValue()); - - decendingTailMap = decendingMap.tailMap(new Integer(104).toString(), - false); - value = new Integer(109); - entry = decendingTailMap.higherEntry(value.toString()); - assertEquals(103, entry.getValue()); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - value = new Integer(101); - assertNull(decendingMap.higherEntry(value.toString())); - - for (int i = 109; i > 101; i--) { - value = new Integer(i); - entry = decendingMap.higherEntry(value.toString()); - assertEquals(value - 1, entry.getValue()); - } - - value = new Integer(2); - entry = decendingMap.higherEntry(value.toString()); - assertEquals(109, entry.getValue()); - - decendingTailMap = decendingMap.tailMap(new Integer(104).toString(), - false); - value = new Integer(109); - entry = decendingTailMap.higherEntry(value.toString()); - assertEquals(103, entry.getValue()); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - value = new Integer(100); - assertNull(decendingMap.higherEntry(value.toString())); - - for (int i = 109; i > 100; i--) { - value = new Integer(i); - entry = decendingMap.higherEntry(value.toString()); - assertEquals(value - 1, entry.getValue()); - } - - value = new Integer(2); - entry = decendingMap.higherEntry(value.toString()); - assertEquals(109, entry.getValue()); - - decendingTailMap = decendingMap.tailMap(new Integer(104).toString(), - false); - value = new Integer(109); - entry = decendingTailMap.higherEntry(value.toString()); - assertEquals(103, entry.getValue()); - } - - public void test_DescendingSubMap_lowerEntry() { - NavigableMap decendingMap; - NavigableMap decendingHeadMap; - Integer value; - Entry entry; - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - value = new Integer(99); - assertNull(decendingMap.lowerEntry(value.toString())); - for (int i = 100; i < 108; i++) { - value = new Integer(i); - entry = decendingMap.lowerEntry(value.toString()); - assertEquals(value + 1, entry.getValue()); - } - value = new Integer(109); - assertNull(decendingMap.lowerEntry(value.toString())); - - decendingHeadMap = decendingMap.headMap(new Integer(103).toString(), - false); - for (int i = 104; i < 106; i++) { - value = new Integer(i); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertEquals(value + 1, entry.getValue()); - } - value = new Integer(102); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertEquals(104, entry.getValue()); - - value = new Integer(109); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertNull(entry); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - value = new Integer(99); - assertNull(decendingMap.lowerEntry(value.toString())); - for (int i = 100; i < 109; i++) { - value = new Integer(i); - entry = decendingMap.lowerEntry(value.toString()); - assertEquals(value + 1, entry.getValue()); - } - value = new Integer(110); - assertNull(decendingMap.lowerEntry(value.toString())); - - decendingHeadMap = decendingMap.headMap(new Integer(103).toString(), - false); - for (int i = 104; i < 109; i++) { - value = new Integer(i); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertEquals(value + 1, entry.getValue()); - } - value = new Integer(102); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertEquals(104, entry.getValue()); - - value = new Integer(2); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertNull(entry); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - value = new Integer(99); - assertNull(decendingMap.lowerEntry(value.toString())); - for (int i = 100; i < 108; i++) { - value = new Integer(i); - entry = decendingMap.lowerEntry(value.toString()); - assertEquals(value + 1, entry.getValue()); - } - value = new Integer(109); - assertNull(decendingMap.lowerEntry(value.toString())); - - decendingHeadMap = decendingMap.headMap(new Integer(103).toString(), - false); - for (int i = 104; i < 107; i++) { - value = new Integer(i); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertEquals(value + 1, entry.getValue()); - } - value = new Integer(102); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertEquals(104, entry.getValue()); - - value = new Integer(2); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertNull(entry); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - value = new Integer(99); - assertNull(decendingMap.lowerEntry(value.toString())); - for (int i = 100; i < 109; i++) { - value = new Integer(i); - entry = decendingMap.lowerEntry(value.toString()); - assertEquals(value + 1, entry.getValue()); - } - value = new Integer(110); - assertNull(decendingMap.lowerEntry(value.toString())); - - decendingHeadMap = decendingMap.headMap(new Integer(103).toString(), - false); - for (int i = 104; i < 109; i++) { - value = new Integer(i); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertEquals(value + 1, entry.getValue()); - } - value = new Integer(102); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertEquals(104, entry.getValue()); - - value = new Integer(2); - entry = decendingHeadMap.lowerEntry(value.toString()); - assertNull(entry); - } - - public void test_DescendingSubMap_pollFirstEntry() { - NavigableMap decendingMap = tm.descendingMap(); - assertEquals(999, decendingMap.pollFirstEntry().getValue()); - - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - assertEquals(108, decendingMap.pollFirstEntry().getValue()); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - assertEquals(109, decendingMap.pollFirstEntry().getValue()); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - assertEquals(107, decendingMap.pollFirstEntry().getValue()); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - assertEquals(106, decendingMap.pollFirstEntry().getValue()); - } - - public void test_DescendingSubMap_pollLastEntry() { - NavigableMap decendingMap = tm.descendingMap(); - assertEquals(0, decendingMap.pollLastEntry().getValue()); - - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - assertEquals(101, decendingMap.pollLastEntry().getValue()); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - assertEquals(102, decendingMap.pollLastEntry().getValue()); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - assertEquals(100, decendingMap.pollLastEntry().getValue()); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - assertEquals(103, decendingMap.pollLastEntry().getValue()); - } - - public void test_DescendingSubMap_values() { - NavigableMap decendingMap = tm.descendingMap(); - Collection values = decendingMap.values(); - assertFalse(values.isEmpty()); - assertFalse(values.contains(1000)); - for (int i = 999; i > 0; i--) { - assertTrue(values.contains(i)); - } - assertTrue(values.contains(0)); - - String endKey = new Integer(99).toString(); - NavigableMap headMap = decendingMap.headMap(endKey, false); - values = headMap.values(); - Iterator it = values.iterator(); - for (int i = 999; i > 990; i--) { - assertTrue(values.contains(i)); - assertEquals(i, it.next()); - } - - String startKey = new Integer(11).toString(); - NavigableMap tailMap = decendingMap.tailMap(startKey, false); - values = tailMap.values(); - it = values.iterator(); - for (int i = 109; i > 100; i--) { - assertTrue(values.contains(i)); - assertEquals(i, it.next()); - } - - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - values = decendingMap.values(); - assertFalse(values.isEmpty()); - assertFalse(values.contains(109)); - for (int i = 108; i > 100; i--) { - assertTrue(values.contains(i)); - } - assertFalse(values.contains(100)); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - values = decendingMap.values(); - assertFalse(values.isEmpty()); - assertFalse(values.contains(100)); - for (int i = 108; i > 100; i--) { - assertTrue(values.contains(i)); - } - assertTrue(values.contains(109)); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - values = decendingMap.values(); - assertFalse(values.isEmpty()); - assertTrue(values.contains(100)); - for (int i = 108; i > 100; i--) { - assertTrue(values.contains(i)); - } - assertFalse(values.contains(109)); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - values = decendingMap.values(); - assertFalse(values.isEmpty()); - assertTrue(values.contains(100)); - for (int i = 108; i > 100; i--) { - assertTrue(values.contains(i)); - } - assertTrue(values.contains(109)); - } - - public void test_DescendingSubMap_headMap() { - NavigableMap decendingMap = tm.descendingMap(); - String endKey = new Integer(0).toString(), key; - SortedMap subDecendingMap_Included = decendingMap.headMap(endKey, true); - SortedMap subDecendingMap_Excluded = decendingMap - .headMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 1; i < 1000; i++) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(1000).toString(); - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - endKey = new Integer(100).toString(); - try { - decendingMap.headMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - for (int i = 102; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(109).toString(); - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - endKey = new Integer(100).toString(); - try { - decendingMap.headMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - for (int i = 102; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(109).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - endKey = new Integer(100).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - for (int i = 102; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(109).toString(); - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - endKey = new Integer(100).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - for (int i = 102; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(109).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - - // With Comparator - - decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .descendingMap(); - endKey = new Integer(100).toString(); - try { - decendingMap.headMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - for (int i = 102; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(109).toString(); - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .descendingMap(); - endKey = new Integer(100).toString(); - try { - decendingMap.headMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - for (int i = 102; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(109).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - - decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded_comparator) - .descendingMap(); - endKey = new Integer(100).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - for (int i = 102; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(109).toString(); - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded_comparator) - .descendingMap(); - endKey = new Integer(100).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.headMap(endKey, true); - subDecendingMap_Excluded = decendingMap.headMap(endKey, false); - - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - for (int i = 102; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(109).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - - public void test_DescendingSubMap_subMap() { - NavigableMap descendingMap = tm.descendingMap(); - String startKey = new Integer(109).toString(); - String endKey = new Integer(100).toString(); - try { - descendingMap.subMap(endKey, false, startKey, false); - } catch (IllegalArgumentException e) { - // Expected - } - - SortedMap subDescendingMap = descendingMap.subMap(startKey, false, - endKey, false); - String key = new Integer(100).toString(); - assertFalse(subDescendingMap.containsKey(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDescendingMap.containsKey(key)); - } - key = new Integer(109).toString(); - assertFalse(subDescendingMap.containsKey(key)); - - subDescendingMap = descendingMap.subMap(startKey, false, endKey, true); - key = new Integer(100).toString(); - assertTrue(subDescendingMap.containsKey(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDescendingMap.containsKey(key)); - } - key = new Integer(109).toString(); - assertFalse(subDescendingMap.containsKey(key)); - - subDescendingMap = descendingMap.subMap(startKey, true, endKey, false); - key = new Integer(100).toString(); - assertFalse(subDescendingMap.containsKey(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDescendingMap.containsKey(key)); - } - key = new Integer(109).toString(); - assertTrue(subDescendingMap.containsKey(key)); - - subDescendingMap = descendingMap.subMap(startKey, true, endKey, true); - key = new Integer(100).toString(); - assertTrue(subDescendingMap.containsKey(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(subDescendingMap.containsKey(key)); - } - key = new Integer(109).toString(); - assertTrue(subDescendingMap.containsKey(key)); - - TreeMap treeMap = new TreeMap(); - for (int i = -10; i < 10; i++) { - treeMap.put(i, String.valueOf(i)); - } - descendingMap = treeMap.descendingMap(); - subDescendingMap = descendingMap.subMap(5, 0); - assertEquals(5, subDescendingMap.size()); - } - - public void test_DescendingSubMap_tailMap() { - // tm - NavigableMap decendingMap = tm.descendingMap(); - String endKey = new Integer(1000).toString(), key; - SortedMap subDecendingMap_Included = decendingMap.tailMap(endKey, true); - SortedMap subDecendingMap_Excluded = decendingMap - .tailMap(endKey, false); - - key = endKey; - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - key = new Integer(100).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - - key = new Integer(10).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - - key = new Integer(1).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - - key = new Integer(0).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(999).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 998; i > 0; i--) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(0).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(0).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - assertEquals(1, subDecendingMap_Included.size()); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.isEmpty()); - - // navigableMap_startExcluded_endExcluded - decendingMap = navigableMap_startExcluded_endExcluded.descendingMap(); - endKey = new Integer(110).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(109).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(108).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 107; i > 100; i--) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(100).toString(); - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Included.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertEquals(1, subDecendingMap_Included.size()); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.isEmpty()); - - endKey = new Integer(100).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - assertTrue(subDecendingMap_Excluded.isEmpty()); - - endKey = new Integer(99).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // navigableMap_startExcluded_endIncluded - decendingMap = navigableMap_startExcluded_endIncluded.descendingMap(); - endKey = new Integer(110).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(109).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(108).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 107; i > 100; i--) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(100).toString(); - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Included.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertEquals(1, subDecendingMap_Included.size()); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.isEmpty()); - - endKey = new Integer(100).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - assertTrue(subDecendingMap_Excluded.isEmpty()); - - endKey = new Integer(99).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // navigableMap_startIncluded_endExcluded - decendingMap = navigableMap_startIncluded_endExcluded.descendingMap(); - endKey = new Integer(110).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(109).toString(); - try { - decendingMap.tailMap(endKey, true); - - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(108).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 107; i > 100; i--) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(100).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Included.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertEquals(2, subDecendingMap_Included.size()); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(100).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(99).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // navigableMap_startIncluded_endIncluded - decendingMap = navigableMap_startIncluded_endIncluded.descendingMap(); - endKey = new Integer(110).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(109).toString(); - try { - decendingMap.tailMap(endKey, true); - - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(108).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 107; i > 100; i--) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(100).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Included.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertEquals(2, subDecendingMap_Included.size()); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(100).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(99).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // With Comparator - decendingMap = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .descendingMap(); - endKey = new Integer(110).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(109).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(108).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 107; i > 100; i--) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(100).toString(); - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Included.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertEquals(1, subDecendingMap_Included.size()); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.isEmpty()); - - endKey = new Integer(100).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - assertTrue(subDecendingMap_Excluded.isEmpty()); - - endKey = new Integer(99).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - decendingMap = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .descendingMap(); - endKey = new Integer(110).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(109).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(108).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 107; i > 100; i--) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(100).toString(); - assertFalse(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Included.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertEquals(1, subDecendingMap_Included.size()); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.isEmpty()); - - endKey = new Integer(100).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - assertTrue(subDecendingMap_Excluded.isEmpty()); - - endKey = new Integer(99).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // navigableMap_startIncluded_endExcluded - decendingMap = ((NavigableMap) subMap_startIncluded_endExcluded) - .descendingMap(); - endKey = new Integer(110).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(109).toString(); - try { - decendingMap.tailMap(endKey, true); - - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(108).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 107; i > 100; i--) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(100).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Included.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertEquals(2, subDecendingMap_Included.size()); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(100).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(99).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - decendingMap = ((NavigableMap) subMap_startIncluded_endIncluded) - .descendingMap(); - endKey = new Integer(110).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(109).toString(); - try { - decendingMap.tailMap(endKey, true); - - } catch (IllegalArgumentException e) { - // Expected - } - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(108).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - for (int i = 107; i > 100; i--) { - key = new Integer(i).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Excluded.containsKey(key)); - } - key = new Integer(100).toString(); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertTrue(subDecendingMap_Included.containsKey(key)); - - endKey = new Integer(101).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertEquals(2, subDecendingMap_Included.size()); - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(100).toString(); - subDecendingMap_Included = decendingMap.tailMap(endKey, true); - subDecendingMap_Excluded = decendingMap.tailMap(endKey, false); - key = endKey; - assertTrue(subDecendingMap_Included.containsKey(key)); - assertFalse(subDecendingMap_Excluded.containsKey(key)); - - endKey = new Integer(99).toString(); - try { - decendingMap.tailMap(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - decendingMap.tailMap(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } - - public void test_Entry_setValue() { - TreeMap treeMap = new TreeMap(); - Integer value = null; - for (int i = 0; i < 50; i++) { - value = new Integer(i); - treeMap.put(value, value); - } - Map checkedMap = Collections.checkedMap(treeMap, Integer.class, - Integer.class); - Set entrySet = checkedMap.entrySet(); - Iterator iterator = entrySet.iterator(); - Entry entry; - value = new Integer(0); - for (; iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.setValue(value + 1)); - assertEquals(value + 1, entry.getValue()); - } - } - - public void test_DescendingSubMapEntrySet_comparator() { - Set entrySet; - NavigableSet descendingSet; - Comparator comparator; - Entry[] entryArray; - Integer value1, value2; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - assertNull(((NavigableSet) entrySet).comparator()); - comparator = descendingSet.comparator(); - assertNotNull(comparator); - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 1; i < entryArray.length; i++) { - value1 = (Integer) entryArray[i - 1].getValue(); - value2 = (Integer) entryArray[i].getValue(); - assertTrue(value1 > value2); - assertTrue(comparator.compare(value1, value2) < 0); - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - assertNull(((NavigableSet) entrySet).comparator()); - comparator = descendingSet.comparator(); - assertNotNull(comparator); - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 1; i < entryArray.length; i++) { - value1 = (Integer) entryArray[i - 1].getValue(); - value2 = (Integer) entryArray[i].getValue(); - assertTrue(value1 > value2); - assertTrue(comparator.compare(value1, value2) < 0); - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - assertNull(((NavigableSet) entrySet).comparator()); - comparator = descendingSet.comparator(); - assertNotNull(comparator); - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 1; i < entryArray.length; i++) { - value1 = (Integer) entryArray[i - 1].getValue(); - value2 = (Integer) entryArray[i].getValue(); - assertTrue(value1 > value2); - assertTrue(comparator.compare(value1, value2) < 0); - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - assertNull(((NavigableSet) entrySet).comparator()); - comparator = descendingSet.comparator(); - assertNotNull(comparator); - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 1; i < entryArray.length; i++) { - value1 = (Integer) entryArray[i - 1].getValue(); - value2 = (Integer) entryArray[i].getValue(); - assertTrue(value1 > value2); - assertTrue(comparator.compare(value1, value2) < 0); - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - assertNotNull(descendingSet.comparator()); - } - } - - public void test_DescendingSubMapEntrySet_descendingSet() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet, descendingSet, descendingDescedingSet; - Entry[] ascendingEntryArray, descendingDescendingArray; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - descendingDescedingSet = descendingSet.descendingSet(); - ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet - .toArray(new Entry[ascendingSubMapEntrySet.size()]); - - descendingDescendingArray = (Entry[]) descendingDescedingSet - .toArray(new Entry[descendingDescedingSet.size()]); - - assertEquals(ascendingEntryArray.length, - descendingDescendingArray.length); - for (int i = 0; i < ascendingEntryArray.length; i++) { - assertEquals(ascendingEntryArray[i], - descendingDescendingArray[i]); - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - descendingDescedingSet = descendingSet.descendingSet(); - ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet - .toArray(new Entry[ascendingSubMapEntrySet.size()]); - - descendingDescendingArray = (Entry[]) descendingDescedingSet - .toArray(new Entry[descendingDescedingSet.size()]); - - assertEquals(ascendingEntryArray.length, - descendingDescendingArray.length); - for (int i = 0; i < ascendingEntryArray.length; i++) { - assertEquals(ascendingEntryArray[i], - descendingDescendingArray[i]); - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - descendingDescedingSet = descendingSet.descendingSet(); - ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet - .toArray(new Entry[ascendingSubMapEntrySet.size()]); - - descendingDescendingArray = (Entry[]) descendingDescedingSet - .toArray(new Entry[descendingDescedingSet.size()]); - - assertEquals(ascendingEntryArray.length, - descendingDescendingArray.length); - for (int i = 0; i < ascendingEntryArray.length; i++) { - assertEquals(ascendingEntryArray[i], - descendingDescendingArray[i]); - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - descendingDescedingSet = descendingSet.descendingSet(); - ascendingEntryArray = (Entry[]) ascendingSubMapEntrySet - .toArray(new Entry[ascendingSubMapEntrySet.size()]); - - descendingDescendingArray = (Entry[]) descendingDescedingSet - .toArray(new Entry[descendingDescedingSet.size()]); - - assertEquals(ascendingEntryArray.length, - descendingDescendingArray.length); - for (int i = 0; i < ascendingEntryArray.length; i++) { - assertEquals(ascendingEntryArray[i], - descendingDescendingArray[i]); - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet();// 0...2 - if (entrySet instanceof NavigableSet) { - // [2...0] - descendingSet = ((NavigableSet) entrySet).descendingSet(); - // [0...2] - descendingDescedingSet = descendingSet.descendingSet(); - Iterator iterator = descendingDescedingSet.iterator(); - assertEquals(0, ((Entry) iterator.next()).getValue()); - } - - String startKey = new Integer(2).toString(); - entrySet = tm.tailMap(startKey, true).entrySet();// 2... - if (entrySet instanceof NavigableSet) { - // [2...0] - descendingSet = ((NavigableSet) entrySet).descendingSet(); - // [0...2] - descendingDescedingSet = descendingSet.descendingSet(); - Iterator iterator = descendingDescedingSet.iterator(); - assertEquals(2, ((Entry) iterator.next()).getValue()); - } - - } - - public void test_DescendingSubMapEntrySet_first() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet, descendingSet; - Entry entry; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - entry = (Entry) descendingSet.first(); - assertEquals(101, entry.getValue()); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - entry = (Entry) descendingSet.first(); - assertEquals(101, entry.getValue()); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - entry = (Entry) descendingSet.first(); - assertEquals(100, entry.getValue()); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - entry = (Entry) descendingSet.first(); - assertEquals(100, entry.getValue()); - } - } - - public void test_DescendingSubMapEntrySet_last() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet, descendingSet; - Entry entry; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - entry = (Entry) descendingSet.last(); - assertEquals(108, entry.getValue()); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - entry = (Entry) descendingSet.last(); - assertEquals(109, entry.getValue()); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - entry = (Entry) descendingSet.last(); - assertEquals(108, entry.getValue()); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - entry = (Entry) descendingSet.last(); - assertEquals(109, entry.getValue()); - } - } - - public void test_DescendingSubMapEntrySet_pollFirst_startExcluded_endExcluded() { - Set entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - Entry entry; - if (entrySet instanceof NavigableSet) { - NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - assertEquals(8, descendingSubMapEntrySet.size()); - for (int i = 101; i < 109; i++) { - entry = (Entry) descendingSubMapEntrySet.pollFirst(); - assertEquals(i, entry.getValue()); - } - assertNull(descendingSubMapEntrySet.pollFirst()); - } - } - - public void test_DescendingSubMapEntrySet_pollFirst_startExcluded_endIncluded() { - Set entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - Entry entry; - if (entrySet instanceof NavigableSet) { - NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - assertEquals(9, descendingSubMapEntrySet.size()); - for (int i = 101; i < 110; i++) { - entry = (Entry) descendingSubMapEntrySet.pollFirst(); - assertEquals(i, entry.getValue()); - } - assertNull(descendingSubMapEntrySet.pollFirst()); - } - } - - public void test_DescendingSubMapEntrySet_pollFirst_startIncluded_endExcluded() { - Set entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - Entry entry; - if (entrySet instanceof NavigableSet) { - NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - assertEquals(9, descendingSubMapEntrySet.size()); - for (int i = 100; i < 109; i++) { - entry = (Entry) descendingSubMapEntrySet.pollFirst(); - assertEquals(i, entry.getValue()); - } - assertNull(descendingSubMapEntrySet.pollFirst()); - } - } - - public void test_DescendingSubMapEntrySet_pollFirst_startIncluded_endIncluded() { - Set entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - Entry entry; - if (entrySet instanceof NavigableSet) { - NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - assertEquals(10, descendingSubMapEntrySet.size()); - for (int i = 100; i < 110; i++) { - entry = (Entry) descendingSubMapEntrySet.pollFirst(); - assertEquals(i, entry.getValue()); - } - assertNull(descendingSubMapEntrySet.pollFirst()); - } - } - - public void test_DescendingSubMapEntrySet_pollFirst() { - String key = new Integer(2).toString(); - Set entrySet = tm.headMap(key, true).entrySet();// [0...2] - NavigableSet descendingEntrySet; - Entry entry; - - if (entrySet instanceof NavigableSet) { - // [2...0] - descendingEntrySet = ((NavigableSet) entrySet).descendingSet(); - entry = (Entry) descendingEntrySet.pollFirst(); - assertEquals(0, entry.getValue()); - } - - entrySet = tm.tailMap(key, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingEntrySet = ((NavigableSet) entrySet).descendingSet(); - entry = (Entry) descendingEntrySet.pollFirst(); - assertEquals(2, entry.getValue()); - } - } - - public void test_DescendingSubMapEntrySet_pollLast_startExcluded_endExclued() { - Set entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - Entry entry; - if (entrySet instanceof NavigableSet) { - NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - assertEquals(8, descendingSubMapEntrySet.size()); - for (int i = 108; i > 100; i--) { - entry = (Entry) descendingSubMapEntrySet.pollLast(); - assertEquals(i, entry.getValue()); - } - assertNull(descendingSubMapEntrySet.pollFirst()); - } - } - - public void test_DescendingSubMapEntrySet_pollLast_startExcluded_endInclued() { - Set entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - Entry entry; - if (entrySet instanceof NavigableSet) { - NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - assertEquals(9, descendingSubMapEntrySet.size()); - for (int i = 109; i > 100; i--) { - entry = (Entry) descendingSubMapEntrySet.pollLast(); - assertEquals(i, entry.getValue()); - } - assertNull(descendingSubMapEntrySet.pollFirst()); - } - } - - public void test_DescendingSubMapEntrySet_pollLast_startIncluded_endExclued() { - Set entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - Entry entry; - if (entrySet instanceof NavigableSet) { - NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - assertEquals(9, descendingSubMapEntrySet.size()); - for (int i = 108; i > 99; i--) { - entry = (Entry) descendingSubMapEntrySet.pollLast(); - assertEquals(i, entry.getValue()); - } - assertNull(descendingSubMapEntrySet.pollFirst()); - } - } - - public void test_DescendingSubMapEntrySet_pollLast_startIncluded_endInclued() { - Set entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - Entry entry; - if (entrySet instanceof NavigableSet) { - NavigableSet descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - assertEquals(10, descendingSubMapEntrySet.size()); - for (int i = 109; i > 99; i--) { - entry = (Entry) descendingSubMapEntrySet.pollLast(); - assertEquals(i, entry.getValue()); - } - assertNull(descendingSubMapEntrySet.pollFirst()); - } - } - - public void test_DescendingSubMapEntrySet_pollLast() { - String key = new Integer(2).toString(); - Set entrySet = tm.headMap(key, true).entrySet();// [0...2] - NavigableSet descendingEntrySet; - Entry entry; - - if (entrySet instanceof NavigableSet) { - // [2...0] - descendingEntrySet = ((NavigableSet) entrySet).descendingSet(); - entry = (Entry) descendingEntrySet.pollLast(); - assertEquals(2, entry.getValue()); - } - - entrySet = tm.tailMap(key, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingEntrySet = ((NavigableSet) entrySet).descendingSet(); - entry = (Entry) descendingEntrySet.pollLast(); - assertEquals(999, entry.getValue()); - } - } - - public void test_DescendingSubMapEntrySet_descendingIterator() { - Set entrySet; - NavigableSet descendingSet; - Iterator iterator; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - iterator = descendingSet.iterator(); - for (int value = 108; value > 100; value--) { - assertTrue(iterator.hasNext()); - assertEquals(value, ((Entry) iterator.next()).getValue()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - iterator = descendingSet.iterator(); - for (int value = 109; value > 100; value--) { - assertTrue(iterator.hasNext()); - assertEquals(value, ((Entry) iterator.next()).getValue()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - iterator = descendingSet.iterator(); - for (int value = 108; value > 99; value--) { - assertTrue(iterator.hasNext()); - assertEquals(value, ((Entry) iterator.next()).getValue()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - iterator = descendingSet.iterator(); - for (int value = 109; value > 99; value--) { - assertTrue(iterator.hasNext()); - assertEquals(value, ((Entry) iterator.next()).getValue()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet();// 0...2 - if (entrySet instanceof NavigableSet) { - // [2...0] - descendingSet = ((NavigableSet) entrySet).descendingSet(); - iterator = descendingSet.descendingIterator(); - assertEquals(0, ((Entry) iterator.next()).getValue());// 0...2 - } - } - - public void test_DescendingSubMapEntrySet_headSet() { - Set entrySet, headSet; - NavigableSet descendingSubMapEntrySet; - Iterator iterator, headSetIterator; - Entry entry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = descendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 108; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = descendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 108; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = descendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 108; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = descendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 109; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = descendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 109; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = descendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 109; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = descendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 108; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = descendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 108; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = descendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 108; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = descendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 109; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = descendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 109; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = descendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 109; headSetIterator.hasNext(); value--) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet();// 0...2 - if (entrySet instanceof NavigableSet) { - // [2...0] - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - iterator.next();// 2 - iterator.next();// 199 - entry = (Entry) iterator.next();// 198 - headSet = descendingSubMapEntrySet.headSet(entry); - assertEquals(2, headSet.size());// 2 199 - headSetIterator = headSet.iterator(); - assertEquals(2, ((Entry) headSetIterator.next()).getValue()); - assertEquals(199, ((Entry) headSetIterator.next()).getValue()); - - headSet = descendingSubMapEntrySet.headSet(entry, true); - assertEquals(3, headSet.size());// 2 199 - headSetIterator = headSet.iterator(); - assertEquals(2, ((Entry) headSetIterator.next()).getValue()); - assertEquals(199, ((Entry) headSetIterator.next()).getValue()); - assertEquals(198, ((Entry) headSetIterator.next()).getValue()); - } - } - - public void test_DescendingSubMapEntrySet_tailSet() { - Set entrySet, tailSet; - NavigableSet descendingSubMapEntrySet; - Iterator iterator, tailSetIterator; - Entry entry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = descendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = descendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value - 1, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = descendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = descendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = descendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value - 1, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = descendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = descendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = descendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value - 1, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = descendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = descendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = descendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value - 1, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = descendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value--) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet();// 0...2 - if (entrySet instanceof NavigableSet) { - // [2...0] - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - iterator.next();// 2 - entry = (Entry) iterator.next();// 199 - tailSet = descendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - assertEquals(199, ((Entry) tailSetIterator.next()).getValue()); - - tailSet = descendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - assertEquals(198, ((Entry) tailSetIterator.next()).getValue()); - - tailSet = descendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - assertEquals(199, ((Entry) tailSetIterator.next()).getValue()); - } - } - - public void test_DescendingSubMapEntrySet_subSet() { - Set entrySet, subSet; - NavigableSet descendingSubMapEntrySet; - Entry startEntry, endEntry; - Iterator subSetIterator; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - Iterator iteratorStart = descendingSubMapEntrySet.iterator(); - while (iteratorStart.hasNext()) { - startEntry = (Entry) iteratorStart.next(); - Iterator iteratorEnd = descendingSubMapEntrySet.iterator(); - while (iteratorEnd.hasNext()) { - endEntry = (Entry) iteratorEnd.next(); - int startIndex = (Integer) startEntry.getValue(); - int endIndex = (Integer) endEntry.getValue(); - if (startIndex < endIndex) { - try { - descendingSubMapEntrySet.subSet(startEntry, - endEntry); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = descendingSubMapEntrySet.subSet(startEntry, - endEntry); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - false, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator - .hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - false, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator - .hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - true, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - true, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - } - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - // [2...0] - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - Iterator iterator = descendingSubMapEntrySet.iterator(); - startEntry = (Entry) iterator.next(); - iterator.next(); - endEntry = (Entry) iterator.next(); - subSet = descendingSubMapEntrySet.subSet(startEntry, endEntry); - assertEquals(2, subSet.size()); - - subSet = descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(199, ((Entry) subSetIterator.next()).getValue()); - - subSet = descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(199, ((Entry) subSetIterator.next()).getValue()); - assertEquals(198, ((Entry) subSetIterator.next()).getValue()); - - subSet = descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, false); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(2, ((Entry) subSetIterator.next()).getValue()); - assertEquals(199, ((Entry) subSetIterator.next()).getValue()); - - subSet = descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, true); - assertEquals(3, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(2, ((Entry) subSetIterator.next()).getValue()); - assertEquals(199, ((Entry) subSetIterator.next()).getValue()); - assertEquals(198, ((Entry) subSetIterator.next()).getValue()); - } - - // With Comnparator - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - Iterator iteratorStart = descendingSubMapEntrySet.iterator(); - while (iteratorStart.hasNext()) { - startEntry = (Entry) iteratorStart.next(); - Iterator iteratorEnd = descendingSubMapEntrySet.iterator(); - while (iteratorEnd.hasNext()) { - endEntry = (Entry) iteratorEnd.next(); - int startIndex = (Integer) startEntry.getValue(); - int endIndex = (Integer) endEntry.getValue(); - if (startIndex < endIndex) { - try { - descendingSubMapEntrySet.subSet(startEntry, - endEntry); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingSubMapEntrySet.subSet(startEntry, true, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = descendingSubMapEntrySet.subSet(startEntry, - endEntry); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - false, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator - .hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - false, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator - .hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - true, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = descendingSubMapEntrySet.subSet(startEntry, - true, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - } - } - } - } - } - - public void test_DescendingSubMapEntrySet_lower() { - Set entrySet, subSet; - NavigableSet descendingSubMapEntrySet; - Iterator iterator; - Entry entry, lowerEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - - // System.out.println(descendingSubMapEntrySet); - // System.out.println(tm); - Object afterEnd = this.subMap_default_afterEnd_109.entrySet() - .iterator().next(); - // System.out.println("o:" + afterEnd); - Object x = descendingSubMapEntrySet.lower(afterEnd); - // System.out.println("x:" + x); - assertNull(x); - Object beforeStart = this.subMap_default_beforeStart_100.entrySet() - .iterator().next(); - // System.out.println("before: " + beforeStart); - Object y = descendingSubMapEntrySet.lower(beforeStart); - // System.out.println("y: " + y); - assertNotNull(y); - assertEquals(101, (((Entry) y).getValue())); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - iterator.next();// 2 - iterator.next();// 199 - entry = (Entry) iterator.next();// 198 - lowerEntry = (Entry) descendingSubMapEntrySet.lower(entry); - assertEquals(199, lowerEntry.getValue()); - } - } - - public void test_DescendingSubMapEntrySet_higher() { - Set entrySet, subSet; - NavigableSet descendingSubMapEntrySet; - Iterator iterator; - Entry entry, higherEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - - Object afterEnd = this.subMap_default_afterEnd_109.entrySet() - .iterator().next(); - Object x = descendingSubMapEntrySet.higher(afterEnd); - assertNotNull(x); - assertEquals(108, ((Entry) x).getValue()); - Object beforeStart = this.subMap_default_beforeStart_100.entrySet() - .iterator().next(); - Object y = descendingSubMapEntrySet.higher(beforeStart); - assertNull(y); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - iterator.next();// 2 - iterator.next();// 199 - entry = (Entry) iterator.next();// 198 - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - assertEquals(197, higherEntry.getValue()); - } - - // With Comparator - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSubMapEntrySet = ((NavigableSet) entrySet) - .descendingSet(); - iterator = descendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - higherEntry = (Entry) descendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, higherEntry.getValue()); - } else { - assertNull(higherEntry); - } - } - - Object afterEnd = this.subMap_default_afterEnd_109.entrySet() - .iterator().next(); - Object x = descendingSubMapEntrySet.higher(afterEnd); - assertNotNull(x); - assertEquals(108, ((Entry) x).getValue()); - Object beforeStart = this.subMap_default_beforeStart_100.entrySet() - .iterator().next(); - Object y = descendingSubMapEntrySet.higher(beforeStart); - assertNull(y); - } - } - - public void test_DescendingSubMapEntrySet_ceiling() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet, descendingSet; - Entry entry; - Entry[] entryArray; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 108; i < entryArray.length; i++) { - entry = (Entry) descendingSet.ceiling(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - - // System.out.println(descendingSet); - // System.out.println(tm); - Object afterEnd = this.subMap_default_afterEnd_109.entrySet() - .iterator().next(); - // System.out.println("o:" + afterEnd);//110 - Object x = descendingSet.ceiling(afterEnd); - assertNotNull(x); - // System.out.println("x:" + x); - assertEquals(108, ((Entry) x).getValue()); - Object beforeStart = this.subMap_default_beforeStart_100.entrySet() - .iterator().next(); - // System.out.println("before: " + beforeStart);//0 - Object y = descendingSet.ceiling(beforeStart); - assertNull(y); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 109; i < entryArray.length; i++) { - entry = (Entry) descendingSet.ceiling(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 108; i < entryArray.length; i++) { - entry = (Entry) descendingSet.ceiling(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 109; i < entryArray.length; i++) { - entry = (Entry) descendingSet.ceiling(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - try { - descendingSet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - Iterator iterator = descendingSet.iterator(); - Entry ceilingEntry; - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - ceilingEntry = (Entry) descendingSet.ceiling(entry); - assertEquals(entry, ceilingEntry); - } - } - - } - - public void test_DescendingSubMapEntrySet_floor() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet, descendingSet; - Entry entry; - Entry[] entryArray; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 108; i < entryArray.length; i++) { - entry = (Entry) descendingSet.floor(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - - Object afterEnd = this.subMap_default_afterEnd_109.entrySet() - .iterator().next(); - Object x = descendingSet.floor(afterEnd); - assertNull(x); - - Object beforeStart = this.subMap_default_beforeStart_100.entrySet() - .iterator().next(); - Object y = descendingSet.floor(beforeStart); - assertNotNull(y); - assertEquals(101, (((Entry) y).getValue())); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 109; i < entryArray.length; i++) { - entry = (Entry) descendingSet.floor(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 108; i < entryArray.length; i++) { - entry = (Entry) descendingSet.floor(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - try { - descendingSet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 109; i < entryArray.length; i++) { - entry = (Entry) descendingSet.floor(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - - Iterator iterator = descendingSet.iterator(); - Entry floorEntry; - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) descendingSet.floor(entry); - assertEquals(entry, floorEntry); - } - } - - // With Comparator - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 108; i < entryArray.length; i++) { - entry = (Entry) descendingSet.floor(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 109; i < entryArray.length; i++) { - entry = (Entry) descendingSet.floor(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - try { - descendingSet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 108; i < entryArray.length; i++) { - entry = (Entry) descendingSet.floor(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - - entrySet = subMap_startIncluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - descendingSet = ((NavigableSet) entrySet).descendingSet(); - try { - descendingSet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - entryArray = (Entry[]) descendingSet - .toArray(new Entry[descendingSet.size()]); - for (int i = 0, j = 109; i < entryArray.length; i++) { - entry = (Entry) descendingSet.floor(entryArray[i]); - assertEquals(j - i, entry.getValue()); - } - } - } - - public void test_DescendingSubMapKeySet_comparator() { - NavigableSet keySet, descendingKeySet; - Comparator comparator; - String[] keyArray; - Integer value1, value2; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - assertNull(keySet.comparator()); - descendingKeySet = keySet.descendingSet(); - comparator = descendingKeySet.comparator(); - assertNotNull(comparator); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 1; i < keyArray.length; i++) { - value1 = Integer.valueOf(keyArray[i - 1]); - value2 = Integer.valueOf(keyArray[i]); - assertTrue(value1 > value2); - assertTrue(comparator.compare(value1, value2) < 0); - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - assertNull(keySet.comparator()); - descendingKeySet = keySet.descendingSet(); - comparator = descendingKeySet.comparator(); - assertNotNull(comparator); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 1; i < keyArray.length; i++) { - value1 = Integer.valueOf(keyArray[i - 1]); - value2 = Integer.valueOf(keyArray[i]); - assertTrue(value1 > value2); - assertTrue(comparator.compare(value1, value2) < 0); - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - assertNull(keySet.comparator()); - descendingKeySet = keySet.descendingSet(); - comparator = descendingKeySet.comparator(); - assertNotNull(comparator); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 1; i < keyArray.length; i++) { - value1 = Integer.valueOf(keyArray[i - 1]); - value2 = Integer.valueOf(keyArray[i]); - assertTrue(value1 > value2); - assertTrue(comparator.compare(value1, value2) < 0); - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - assertNull(keySet.comparator()); - descendingKeySet = keySet.descendingSet(); - comparator = descendingKeySet.comparator(); - assertNotNull(comparator); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 1; i < keyArray.length; i++) { - value1 = Integer.valueOf(keyArray[i - 1]); - value2 = Integer.valueOf(keyArray[i]); - assertTrue(value1 > value2); - assertTrue(comparator.compare(value1, value2) < 0); - } - - String endKey = new Integer(2).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - assertNull(keySet.comparator()); - descendingKeySet = keySet.descendingSet(); - assertNotNull(descendingKeySet.comparator()); - } - - public void test_AscendingSubMapKeySet_first() { - NavigableSet keySet; - String firstKey1 = new Integer(100).toString(); - String firstKey2 = new Integer(101).toString(); - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - assertEquals(firstKey2, keySet.first()); - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - assertEquals(firstKey2, keySet.first()); - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - assertEquals(firstKey1, keySet.first()); - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - assertEquals(firstKey1, keySet.first()); - } - - public void test_DescendingSubMapKeySet_pollFirst_startExcluded_endExcluded() { - NavigableSet keySet = navigableMap_startExcluded_endExcluded - .navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(8, keySet.size()); - for (int value = 101; value < 109; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_DescendingSubMapKeySet_pollFirst_startExcluded_endIncluded() { - NavigableSet keySet = navigableMap_startExcluded_endIncluded - .navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 101; value < 110; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_DescendingSubMapKeySet_pollFirst_startIncluded_endExcluded() { - NavigableSet keySet = navigableMap_startIncluded_endExcluded - .navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 100; value < 109; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_DescendingSubMapKeySet_pollFirst_startIncluded_endIncluded() { - NavigableSet keySet = navigableMap_startIncluded_endIncluded - .navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(10, keySet.size()); - for (int value = 100; value < 110; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_DescendingSubMapKeySet_pollFirst() { - String endKey = new Integer(2).toString(); - NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - assertEquals(endKey, descendingKeySet.pollFirst()); - } - - public void test_DescendingSubMapKeySet_pollLast_startExcluded_endExcluded() { - NavigableSet keySet = navigableMap_startExcluded_endExcluded - .navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(8, keySet.size()); - for (int value = 108; value > 100; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_DescendingSubMapKeySet_pollLast_startExcluded_endIncluded() { - NavigableSet keySet = navigableMap_startExcluded_endIncluded - .navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 109; value > 100; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_DescendingSubMapKeySet_pollLast_startIncluded_endExcluded() { - NavigableSet keySet = navigableMap_startIncluded_endExcluded - .navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 108; value > 99; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_DescendingSubMapKeySet_pollLast_startIncluded_endIncluded() { - NavigableSet keySet = navigableMap_startIncluded_endIncluded - .navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(10, keySet.size()); - for (int value = 109; value > 99; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_DescendingSubMapKeySet_pollLast() { - String endKey = new Integer(2).toString(); - NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet(); - NavigableSet descendingKeySet = keySet.descendingSet(); - assertEquals(new Integer(0).toString(), descendingKeySet.pollLast()); - } - - public void test_DescendingSubMapKeySet_headSet() { - NavigableSet keySet, descendingKeySet; - SortedSet headSet; - String endKey, key; - Iterator iterator; - int index; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - endKey = new Integer(99).toString(); - try { - descendingKeySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(101).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 108; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 108; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 108; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i - 1, j); - } - - endKey = new Integer(109).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(108, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(108, index); - - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - descendingKeySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - endKey = new Integer(99).toString(); - try { - descendingKeySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(101).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 109; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 109; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 109; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i - 1, j); - } - - endKey = new Integer(109).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(108, index); - - endKey = new Integer(110).toString(); - try { - descendingKeySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - endKey = new Integer(99).toString(); - try { - descendingKeySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(99, index); - - endKey = new Integer(101).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 108; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 108; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 108; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i - 1, j); - } - - endKey = new Integer(109).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(108, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 108; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(108, index); - - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - descendingKeySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - endKey = new Integer(99).toString(); - try { - descendingKeySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(99, index); - - endKey = new Integer(101).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 109; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 109; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 109; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i - 1, j); - } - - endKey = new Integer(109).toString(); - headSet = descendingKeySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = descendingKeySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = descendingKeySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(108, index); - - endKey = new Integer(110).toString(); - try { - descendingKeySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - iterator.next(); - endKey = (String) iterator.next(); - - headSet = descendingKeySet.headSet(endKey); - assertEquals(1, headSet.size()); - - headSet = descendingKeySet.headSet(endKey, false); - assertEquals(1, headSet.size()); - - headSet = descendingKeySet.headSet(endKey, true); - assertEquals(2, headSet.size()); - - key = new Integer(2).toString(); - keySet = tm.tailMap(key, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - iterator.next(); - endKey = (String) iterator.next(); - headSet = descendingKeySet.headSet(endKey); - assertEquals(1, headSet.size()); - iterator = headSet.iterator(); - assertEquals(999, Integer.parseInt((String) iterator.next())); - } - - public void test_DescendingSubMapKeySet_tailSet() { - NavigableSet keySet, descendingKeySet; - SortedSet tailSet; - String startKey, key; - Iterator iterator; - int index; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - startKey = new Integer(99).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - tailSet = descendingKeySet.tailSet(startKey, false); - assertEquals(0, tailSet.size()); - - startKey = new Integer(101).toString(); - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(100, j); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(100, j); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j - 1).toString(), key); - } - assertEquals(101, j); - } - - startKey = new Integer(109).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index - 1).toString(), key); - } - assertEquals(101, index); - - startKey = new Integer(110).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - startKey = new Integer(99).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - tailSet = descendingKeySet.tailSet(startKey, false); - assertEquals(0, tailSet.size()); - - startKey = new Integer(101).toString(); - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(100, j); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(100, j); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j - 1).toString(), key); - } - assertEquals(101, j); - } - - startKey = new Integer(109).toString(); - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(100, index); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index - 1).toString(), key); - } - assertEquals(101, index); - - startKey = new Integer(110).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - startKey = new Integer(99).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - tailSet = descendingKeySet.tailSet(startKey); - assertEquals(1, tailSet.size()); - iterator = tailSet.iterator(); - assertEquals(startKey, iterator.next()); - - tailSet = descendingKeySet.tailSet(startKey, true); - assertEquals(1, tailSet.size()); - iterator = tailSet.iterator(); - assertEquals(startKey, iterator.next()); - - tailSet = descendingKeySet.tailSet(startKey, false); - assertEquals(0, tailSet.size()); - - startKey = new Integer(101).toString(); - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(99, index); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(99, index); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index - 1).toString(), key); - } - assertEquals(100, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(99, j); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(99, j); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j - 1).toString(), key); - } - assertEquals(100, j); - } - - startKey = new Integer(109).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index - 1).toString(), key); - } - assertEquals(100, index); - - startKey = new Integer(110).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - startKey = new Integer(99).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - tailSet = descendingKeySet.tailSet(startKey); - assertEquals(1, tailSet.size()); - iterator = tailSet.iterator(); - assertEquals(startKey, iterator.next()); - - tailSet = descendingKeySet.tailSet(startKey, true); - assertEquals(1, tailSet.size()); - iterator = tailSet.iterator(); - assertEquals(startKey, iterator.next()); - - tailSet = descendingKeySet.tailSet(startKey, false); - assertEquals(0, tailSet.size()); - - startKey = new Integer(101).toString(); - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(99, index); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(99, index); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index - 1).toString(), key); - } - assertEquals(100, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(99, j); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(99, j); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j--) { - key = (String) iterator.next(); - assertEquals(new Integer(j - 1).toString(), key); - } - assertEquals(100, j); - } - - startKey = new Integer(109).toString(); - tailSet = descendingKeySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(99, index); - - tailSet = descendingKeySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(99, index); - - tailSet = descendingKeySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index--) { - key = (String) iterator.next(); - assertEquals(new Integer(index - 1).toString(), key); - } - assertEquals(100, index); - - startKey = new Integer(110).toString(); - try { - descendingKeySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - descendingKeySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - iterator.next(); - startKey = (String) iterator.next(); - - tailSet = descendingKeySet.tailSet(startKey); - assertEquals(112, tailSet.size()); - Iterator tailIterator = tailSet.iterator(); - assertEquals(new Integer(199).toString(), tailIterator.next()); - - tailSet = descendingKeySet.tailSet(startKey, true); - assertEquals(112, tailSet.size()); - tailIterator = tailSet.iterator(); - assertEquals(new Integer(199).toString(), tailIterator.next()); - - tailSet = descendingKeySet.tailSet(startKey, false); - assertEquals(111, tailSet.size()); - tailIterator = tailSet.iterator(); - assertEquals(new Integer(198).toString(), tailIterator.next()); - } - - public void test_DescendingSubMapKeySet_subSet() { - NavigableSet keySet, descendingKeySet; - SortedSet subSet; - String startKey, endKey, key; - Iterator startIterator, endIterator, subSetIterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - startIterator = descendingKeySet.iterator(); - while (startIterator.hasNext()) { - startKey = (String) startIterator.next(); - endIterator = descendingKeySet.iterator(); - while (endIterator.hasNext()) { - endKey = (String) endIterator.next(); - int startIndex = Integer.valueOf(startKey); - int endIndex = Integer.valueOf(endKey); - if (startIndex < endIndex) { - try { - descendingKeySet.subSet(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.subSet(startKey, false, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.subSet(startKey, false, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.subSet(startKey, true, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.subSet(startKey, true, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = descendingKeySet.subSet(startKey, endKey); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = descendingKeySet.subSet(startKey, false, endKey, - false); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = descendingKeySet.subSet(startKey, false, endKey, - true); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = descendingKeySet.subSet(startKey, true, endKey, - false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = descendingKeySet.subSet(startKey, true, endKey, - true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - } - } - } - - endKey = new Integer(2).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - - startKey = (String) iterator.next(); - iterator.next(); - endKey = (String) iterator.next(); - - subSet = descendingKeySet.subSet(startKey, endKey); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(startKey, subSetIterator.next()); - subSetIterator.next(); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = descendingKeySet.subSet(startKey, false, endKey, false); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - subSetIterator.next(); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = descendingKeySet.subSet(startKey, false, endKey, true); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - subSetIterator.next(); - assertEquals(endKey, subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = descendingKeySet.subSet(startKey, true, endKey, false); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(startKey, subSetIterator.next()); - subSetIterator.next(); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = descendingKeySet.subSet(startKey, true, endKey, true); - assertEquals(3, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(startKey, subSetIterator.next()); - subSetIterator.next(); - assertEquals(endKey, subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - startIterator = descendingKeySet.iterator(); - while (startIterator.hasNext()) { - startKey = (String) startIterator.next(); - endIterator = descendingKeySet.iterator(); - while (endIterator.hasNext()) { - endKey = (String) endIterator.next(); - int startIndex = Integer.valueOf(startKey); - int endIndex = Integer.valueOf(endKey); - if (startIndex < endIndex) { - try { - descendingKeySet.subSet(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.subSet(startKey, false, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.subSet(startKey, false, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.subSet(startKey, true, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - descendingKeySet.subSet(startKey, true, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = descendingKeySet.subSet(startKey, endKey); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = descendingKeySet.subSet(startKey, false, endKey, - false); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = descendingKeySet.subSet(startKey, false, endKey, - true); - subSetIterator = subSet.iterator(); - for (int index = startIndex - 1; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = descendingKeySet.subSet(startKey, true, endKey, - false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = descendingKeySet.subSet(startKey, true, endKey, - true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index--) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - } - } - } - } - - public void test_DescendingSubMapKeySet_descendingSet() { - NavigableSet keySet, descendingSet, descendingDescendingSet; - int value; - Iterator iterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingDescendingSet = descendingSet.descendingSet(); - iterator = descendingDescendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 101; iterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertEquals(109, value); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingDescendingSet = descendingSet.descendingSet(); - iterator = descendingDescendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 101; iterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertEquals(110, value); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingDescendingSet = descendingSet.descendingSet(); - iterator = descendingDescendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 100; iterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertEquals(109, value); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingDescendingSet = descendingSet.descendingSet(); - iterator = descendingDescendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 100; iterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertEquals(110, value); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - String endKey = new Integer(2).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingDescendingSet = descendingSet.descendingSet(); - assertEquals(keySet, descendingDescendingSet); - - String startKey = new Integer(2).toString(); - keySet = tm.tailMap(startKey, true).navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingDescendingSet = descendingSet.descendingSet(); - assertEquals(keySet, descendingDescendingSet); - } - - public void test_DescendingSubMapKeySet_descendingIterator() { - NavigableSet keySet, descendingSet; - int value; - Iterator iterator, descendingIterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingIterator = descendingSet.descendingIterator(); - assertTrue(descendingIterator.hasNext()); - for (value = 101; descendingIterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), descendingIterator - .next()); - } - assertEquals(109, value); - try { - descendingIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - descendingSet = descendingSet - .headSet(new Integer(105).toString(), true); - descendingIterator = descendingSet.descendingIterator(); - for (value = 105; descendingIterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), descendingIterator - .next()); - } - - descendingSet = keySet.descendingSet(); - descendingSet = descendingSet - .tailSet(new Integer(105).toString(), true); - descendingIterator = descendingSet.descendingIterator(); - for (value = 101; descendingIterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), descendingIterator - .next()); - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingIterator = descendingSet.descendingIterator(); - assertTrue(descendingIterator.hasNext()); - for (value = 101; descendingIterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), descendingIterator - .next()); - } - assertEquals(110, value); - try { - descendingIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - descendingSet = descendingSet - .headSet(new Integer(105).toString(), true); - descendingIterator = descendingSet.descendingIterator(); - for (value = 105; descendingIterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), descendingIterator - .next()); - } - - descendingSet = keySet.descendingSet(); - descendingSet = descendingSet - .tailSet(new Integer(105).toString(), true); - descendingIterator = descendingSet.descendingIterator(); - for (value = 101; descendingIterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), descendingIterator - .next()); - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingIterator = descendingSet.descendingIterator(); - assertTrue(descendingIterator.hasNext()); - for (value = 100; descendingIterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), descendingIterator - .next()); - } - assertEquals(109, value); - try { - descendingIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - descendingSet = keySet.descendingSet(); - descendingIterator = descendingSet.descendingIterator(); - assertTrue(descendingIterator.hasNext()); - for (value = 100; descendingIterator.hasNext(); value++) { - assertEquals(new Integer(value).toString(), descendingIterator - .next()); - } - assertEquals(110, value); - try { - descendingIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - String endKey = new Integer(2).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - iterator = keySet.iterator(); - - descendingSet = keySet.descendingSet(); - descendingIterator = descendingSet.descendingIterator(); - - while (iterator.hasNext()) { - assertEquals(iterator.next(), descendingIterator.next()); - } - - String startKey = new Integer(2).toString(); - keySet = tm.tailMap(startKey, true).navigableKeySet(); - iterator = keySet.iterator(); - descendingSet = keySet.descendingSet(); - descendingIterator = descendingSet.descendingIterator(); - - while (iterator.hasNext()) { - assertEquals(iterator.next(), descendingIterator.next()); - } - } - - public void test_DescendingSubMapKeySet_lower() { - NavigableSet keySet, descendingKeySet; - Iterator iterator; - String key, lowerKey; - int value, lowerValue; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) descendingKeySet.lower(key); - if (value < 108) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(0).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertEquals(101, Integer.parseInt(lowerKey)); - - key = new Integer(2).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertNull(lowerKey); - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) descendingKeySet.lower(key); - if (value < 109) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(0).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertEquals(101, Integer.parseInt(lowerKey)); - - key = new Integer(2).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertNull(lowerKey); - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) descendingKeySet.lower(key); - if (value < 108) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(0).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertEquals(100, Integer.parseInt(lowerKey)); - - key = new Integer(2).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertNull(lowerKey); - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) descendingKeySet.lower(key); - if (value < 109) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(0).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertEquals(100, Integer.parseInt(lowerKey)); - - key = new Integer(2).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertNull(lowerKey); - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - iterator.next(); - iterator.next(); - key = (String) iterator.next(); - lowerKey = (String) descendingKeySet.lower(key); - assertEquals(new Integer(199).toString(), lowerKey); - try { - descendingKeySet.lower(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - String endKey = key; - - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.lower(endKey)); - - key = new Integer(0).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.lower(endKey)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.lower(endKey)); - assertEquals(new Integer(1).toString(), descendingKeySet.lower(key)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.lower(endKey)); - assertEquals(new Integer(1).toString(), descendingKeySet.lower(key)); - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) descendingKeySet.lower(key); - if (value < 108) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(0).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertEquals(101, Integer.parseInt(lowerKey)); - - key = new Integer(2).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertNull(lowerKey); - - keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) descendingKeySet.lower(key); - if (value < 109) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(0).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertEquals(101, Integer.parseInt(lowerKey)); - - key = new Integer(2).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertNull(lowerKey); - - keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) descendingKeySet.lower(key); - if (value < 108) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(0).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertEquals(100, Integer.parseInt(lowerKey)); - - key = new Integer(2).toString(); - lowerKey = (String) descendingKeySet.lower(key); - assertNull(lowerKey); - - keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) descendingKeySet.lower(key); - if (value < 109) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - } - - public void test_DescendingSubMapKeySet_higher() { - NavigableSet keySet, descendingKeySet; - Iterator iterator; - String key, higherKey; - int value, higherValue; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - higherKey = (String) descendingKeySet.higher(key); - if (value > 101) { - higherValue = Integer.valueOf(higherKey); - assertEquals(value - 1, higherValue); - } else { - assertNull(higherKey); - } - } - - key = new Integer(99999).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals("108", higherKey); - - key = new Integer(-1).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(100).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(0).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(2).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(108, Integer.parseInt(higherKey)); - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - higherKey = (String) descendingKeySet.higher(key); - if (value > 101) { - higherValue = Integer.valueOf(higherKey); - assertEquals(value - 1, higherValue); - } else { - assertNull(higherKey); - } - } - - key = new Integer(99999).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals("109", higherKey); - - key = new Integer(-1).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(100).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(2).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(109, Integer.parseInt(higherKey)); - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - higherKey = (String) descendingKeySet.higher(key); - if (value > 100) { - higherValue = Integer.valueOf(higherKey); - assertEquals(value - 1, higherValue); - } else { - assertNull(higherKey); - } - } - - key = new Integer(99999).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals("108", higherKey); - - key = new Integer(-1).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(100).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(2).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(108, Integer.parseInt(higherKey)); - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - higherKey = (String) descendingKeySet.higher(key); - if (value > 100) { - higherValue = Integer.valueOf(higherKey); - assertEquals(value - 1, higherValue); - } else { - assertNull(higherKey); - } - } - - key = new Integer(99999).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals("109", higherKey); - - key = new Integer(-1).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(100).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(2).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(109, Integer.parseInt(higherKey)); - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - key = (String) iterator.next(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(new Integer(199).toString(), higherKey); - try { - descendingKeySet.higher(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - String endKey = key; - - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.higher(endKey)); - - key = new Integer(0).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.higher(endKey)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertEquals(new Integer(998).toString(), descendingKeySet - .higher(endKey)); - assertNull(descendingKeySet.higher(key)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertEquals(new Integer(998).toString(), descendingKeySet - .higher(endKey)); - assertNull(descendingKeySet.higher(key)); - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - higherKey = (String) descendingKeySet.higher(key); - if (value > 101) { - higherValue = Integer.valueOf(higherKey); - assertEquals(value - 1, higherValue); - } else { - assertNull(higherKey); - } - } - - key = new Integer(99999).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals("108", higherKey); - - key = new Integer(-1).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(100).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(0).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(2).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(108, Integer.parseInt(higherKey)); - - keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - higherKey = (String) descendingKeySet.higher(key); - if (value > 101) { - higherValue = Integer.valueOf(higherKey); - assertEquals(value - 1, higherValue); - } else { - assertNull(higherKey); - } - } - - key = new Integer(99999).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals("109", higherKey); - - key = new Integer(-1).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(100).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(2).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(109, Integer.parseInt(higherKey)); - - keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - higherKey = (String) descendingKeySet.higher(key); - if (value > 100) { - higherValue = Integer.valueOf(higherKey); - assertEquals(value - 1, higherValue); - } else { - assertNull(higherKey); - } - } - - key = new Integer(99999).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals("108", higherKey); - - key = new Integer(-1).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(100).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(2).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(108, Integer.parseInt(higherKey)); - - keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - higherKey = (String) descendingKeySet.higher(key); - if (value > 100) { - higherValue = Integer.valueOf(higherKey); - assertEquals(value - 1, higherValue); - } else { - assertNull(higherKey); - } - } - - key = new Integer(99999).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals("109", higherKey); - - key = new Integer(-1).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(100).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertNull(higherKey); - - key = new Integer(2).toString(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(109, Integer.parseInt(higherKey)); - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - iterator = descendingKeySet.iterator(); - key = (String) iterator.next(); - higherKey = (String) descendingKeySet.higher(key); - assertEquals(new Integer(199).toString(), higherKey); - try { - descendingKeySet.higher(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - endKey = key; - - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.higher(endKey)); - - key = new Integer(0).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.higher(endKey)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertEquals(new Integer(998).toString(), descendingKeySet - .higher(endKey)); - assertNull(descendingKeySet.higher(key)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertEquals(new Integer(998).toString(), descendingKeySet - .higher(endKey)); - assertNull(descendingKeySet.higher(key)); - } - - public void test_DescendingSubMapKeySet_ceiling() { - NavigableSet keySet, descendingKeySet; - String[] keyArray; - String key, ceilingKey; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 108; i < keyArray.length; i++) { - ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]); - assertEquals(new Integer(j - i).toString(), ceilingKey); - } - - key = new Integer(2).toString(); - ceilingKey = (String) descendingKeySet.ceiling(key); - assertEquals(108, Integer.parseInt(ceilingKey)); - - key = new Integer(0).toString(); - ceilingKey = (String) descendingKeySet.ceiling(key); - assertNull(ceilingKey); - - key = new Integer(-1).toString(); - ceilingKey = (String) descendingKeySet.ceiling(key); - assertNull(ceilingKey); - - key = new Integer(99999).toString(); - ceilingKey = (String) descendingKeySet.ceiling(key); - assertEquals(108, Integer.parseInt(ceilingKey)); - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 109; i < keyArray.length; i++) { - ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]); - assertEquals(new Integer(j - i).toString(), ceilingKey); - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 108; i < keyArray.length; i++) { - ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]); - assertEquals(new Integer(j - i).toString(), ceilingKey); - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 109; i < keyArray.length; i++) { - ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]); - assertEquals(new Integer(j - i).toString(), ceilingKey); - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(key, descendingKeySet.ceiling(iterator.next())); - try { - descendingKeySet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - String endKey = key; - - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertEquals(key, descendingKeySet.ceiling(endKey)); - - key = new Integer(0).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.ceiling(endKey)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertEquals(new Integer(999).toString(), descendingKeySet - .ceiling(endKey)); - assertEquals(key, descendingKeySet.ceiling(key)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertEquals(new Integer(998).toString(), descendingKeySet - .ceiling(endKey)); - assertEquals(key, descendingKeySet.ceiling(key)); - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 108; i < keyArray.length; i++) { - ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]); - assertEquals(new Integer(j - i).toString(), ceilingKey); - } - - key = new Integer(2).toString(); - ceilingKey = (String) descendingKeySet.ceiling(key); - assertEquals(108, Integer.parseInt(ceilingKey)); - - key = new Integer(0).toString(); - ceilingKey = (String) descendingKeySet.ceiling(key); - assertNull(ceilingKey); - - keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 109; i < keyArray.length; i++) { - ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]); - assertEquals(new Integer(j - i).toString(), ceilingKey); - } - - keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 108; i < keyArray.length; i++) { - ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]); - assertEquals(new Integer(j - i).toString(), ceilingKey); - } - - keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 109; i < keyArray.length; i++) { - ceilingKey = (String) descendingKeySet.ceiling(keyArray[i]); - assertEquals(new Integer(j - i).toString(), ceilingKey); - } - } - - public void test_DescendingSubMapKeySet_floor() { - NavigableSet keySet, descendingKeySet; - String[] keyArray; - String floorKey; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 108; i < keyArray.length; i++) { - floorKey = (String) descendingKeySet.floor(keyArray[i]); - assertEquals(new Integer(j - i).toString(), floorKey); - } - - String key = new Integer(0).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertEquals(101, Integer.parseInt(floorKey)); - - key = new Integer(2).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertNull(floorKey); - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 109; i < keyArray.length; i++) { - floorKey = (String) descendingKeySet.floor(keyArray[i]); - assertEquals(new Integer(j - i).toString(), floorKey); - } - - key = new Integer(0).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertEquals(101, Integer.parseInt(floorKey)); - - key = new Integer(2).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertNull(floorKey); - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 108; i < keyArray.length; i++) { - floorKey = (String) descendingKeySet.floor(keyArray[i]); - assertEquals(new Integer(j - i).toString(), floorKey); - } - - key = new Integer(0).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertEquals(100, Integer.parseInt(floorKey)); - - key = new Integer(2).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertNull(floorKey); - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 109; i < keyArray.length; i++) { - floorKey = (String) descendingKeySet.floor(keyArray[i]); - assertEquals(new Integer(j - i).toString(), floorKey); - } - - key = new Integer(0).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertEquals(100, Integer.parseInt(floorKey)); - - key = new Integer(2).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertNull(floorKey); - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - Iterator iterator = descendingKeySet.iterator(); - assertEquals(key, descendingKeySet.floor(iterator.next())); - try { - descendingKeySet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - String endKey = key; - - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertEquals(key, descendingKeySet.floor(endKey)); - - key = new Integer(0).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.floor(endKey)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertEquals(new Integer(999).toString(), descendingKeySet - .floor(endKey)); - assertEquals(key, descendingKeySet.floor(key)); - - endKey = new Integer(999).toString(); - keySet = tm.headMap(endKey, false).navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - assertNull(descendingKeySet.floor(endKey)); - assertEquals(key, descendingKeySet.floor(key)); - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 108; i < keyArray.length; i++) { - floorKey = (String) descendingKeySet.floor(keyArray[i]); - assertEquals(new Integer(j - i).toString(), floorKey); - } - - key = new Integer(0).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertEquals(101, Integer.parseInt(floorKey)); - - key = new Integer(2).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertNull(floorKey); - - keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 109; i < keyArray.length; i++) { - floorKey = (String) descendingKeySet.floor(keyArray[i]); - assertEquals(new Integer(j - i).toString(), floorKey); - } - - key = new Integer(0).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertEquals(101, Integer.parseInt(floorKey)); - - key = new Integer(2).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertNull(floorKey); - - keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 108; i < keyArray.length; i++) { - floorKey = (String) descendingKeySet.floor(keyArray[i]); - assertEquals(new Integer(j - i).toString(), floorKey); - } - - key = new Integer(0).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertEquals(100, Integer.parseInt(floorKey)); - - key = new Integer(2).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertNull(floorKey); - - keySet = ((NavigableMap) subMap_startIncluded_endIncluded) - .navigableKeySet(); - descendingKeySet = keySet.descendingSet(); - keyArray = (String[]) descendingKeySet - .toArray(new String[descendingKeySet.size()]); - for (int i = 0, j = 109; i < keyArray.length; i++) { - floorKey = (String) descendingKeySet.floor(keyArray[i]); - assertEquals(new Integer(j - i).toString(), floorKey); - } - - key = new Integer(0).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertEquals(100, Integer.parseInt(floorKey)); - - key = new Integer(2).toString(); - floorKey = (String) descendingKeySet.floor(key); - assertNull(floorKey); - } - - public void test_AscendingSubMapKeySet_last() { - NavigableSet keySet; - String firstKey1 = new Integer(108).toString(); - String firstKey2 = new Integer(109).toString(); - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - assertEquals(firstKey1, keySet.last()); - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - assertEquals(firstKey2, keySet.last()); - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - assertEquals(firstKey1, keySet.last()); - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - assertEquals(firstKey2, keySet.last()); - } - - public void test_AscendingSubMapKeySet_comparator() { - NavigableSet keySet; - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - assertNull(keySet.comparator()); - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - assertNull(keySet.comparator()); - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - assertNull(keySet.comparator()); - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - assertNull(keySet.comparator()); - - String endKey = new Integer(2).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - assertNull(keySet.comparator()); - } - - public void test_AscendingSubMapKeySet_pollFirst_startExcluded_endExcluded() { - NavigableSet keySet = navigableMap_startExcluded_endExcluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(8, keySet.size()); - for (int value = 101; value < 109; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollFirst_startExcluded_endIncluded() { - NavigableSet keySet = navigableMap_startExcluded_endIncluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 101; value < 110; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollFirst_startIncluded_endExcluded() { - NavigableSet keySet = navigableMap_startIncluded_endExcluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 100; value < 109; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollFirst_startIncluded_endIncluded() { - NavigableSet keySet = navigableMap_startIncluded_endIncluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(10, keySet.size()); - for (int value = 100; value < 110; value++) { - assertEquals(new Integer(value).toString(), keySet.pollFirst()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollFirst() { - String endKey = new Integer(2).toString(); - NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet(); - assertEquals(new Integer(0).toString(), keySet.pollFirst()); - - keySet = tm.tailMap(endKey, true).navigableKeySet(); - assertEquals(new Integer(2).toString(), keySet.pollFirst()); - } - - public void test_AscendingSubMapKeySet_pollLast_startExcluded_endExcluded() { - NavigableSet keySet = navigableMap_startExcluded_endExcluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(8, keySet.size()); - for (int value = 108; value > 100; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_AscendingSubMapKeySet_pollLast_startExcluded_endIncluded() { - NavigableSet keySet = navigableMap_startExcluded_endIncluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 109; value > 100; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_AscendingSubMapKeySet_pollLast_startIncluded_endExcluded() { - NavigableSet keySet = navigableMap_startIncluded_endExcluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(9, keySet.size()); - for (int value = 108; value > 99; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_AscendingSubMapKeySet_pollLast_startIncluded_endIncluded() { - NavigableSet keySet = navigableMap_startIncluded_endIncluded - .navigableKeySet(); - Iterator iterator = keySet.iterator(); - assertEquals(10, keySet.size()); - for (int value = 109; value > 99; value--) { - assertEquals(new Integer(value).toString(), keySet.pollLast()); - } - assertEquals(0, keySet.size()); - assertNull(keySet.pollLast()); - } - - public void test_AscendingSubMapKeySet_pollLast() { - String endKey = new Integer(2).toString(); - NavigableSet keySet = tm.headMap(endKey, true).navigableKeySet(); - assertEquals(new Integer(2).toString(), keySet.pollLast()); - - keySet = tm.tailMap(endKey, true).navigableKeySet(); - assertEquals(new Integer(999).toString(), keySet.pollLast()); - } - - public void test_AscendingSubMapKeySet_descendingIterator() { - NavigableSet keySet; - Iterator iterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - iterator = keySet.descendingIterator(); - for (int value = 108; value > 100; value--) { - assertTrue(iterator.hasNext()); - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - iterator = keySet.descendingIterator(); - for (int value = 109; value > 100; value--) { - assertTrue(iterator.hasNext()); - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - iterator = keySet.descendingIterator(); - for (int value = 108; value > 99; value--) { - assertTrue(iterator.hasNext()); - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - iterator = keySet.descendingIterator(); - for (int value = 109; value > 99; value--) { - assertTrue(iterator.hasNext()); - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - String endKey = new Integer(2).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - iterator = keySet.descendingIterator(); - assertEquals(new Integer(2).toString(), iterator.next()); - assertEquals(new Integer(199).toString(), iterator.next()); - } - - public void test_AscendingSubMapKeySet_descendingSet() { - NavigableSet keySet, descendingSet; - Iterator iterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet() - .descendingSet(); - descendingSet = keySet.descendingSet(); - iterator = descendingSet.iterator(); - for (int value = 101; value < 109; value++) { - assertTrue(iterator.hasNext()); - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet() - .descendingSet(); - descendingSet = keySet.descendingSet(); - iterator = descendingSet.iterator(); - for (int value = 101; value < 110; value++) { - assertTrue(iterator.hasNext()); - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet() - .descendingSet(); - descendingSet = keySet.descendingSet(); - iterator = descendingSet.iterator(); - for (int value = 100; value < 109; value++) { - assertTrue(iterator.hasNext()); - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet() - .descendingSet(); - descendingSet = keySet.descendingSet(); - iterator = descendingSet.iterator(); - for (int value = 100; value < 110; value++) { - assertTrue(iterator.hasNext()); - assertEquals(new Integer(value).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - String endKey = new Integer(1).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - descendingSet = keySet.descendingSet(); - iterator = descendingSet.iterator(); - assertEquals(new Integer(1).toString(), iterator.next()); - assertEquals(new Integer(0).toString(), iterator.next()); - } - - public void test_AscendingSubMapKeySet_headSet() { - NavigableSet keySet; - SortedSet headSet; - String endKey, key; - Iterator iterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - try { - keySet.headSet(endKey, true).size(); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(101).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int index; - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(101).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - endKey = new Integer(101).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(102, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - endKey = new Integer(101).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(102, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - key = new Integer(1).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next(); - endKey = (String) iterator.next(); - headSet = keySet.headSet(endKey, false); - assertEquals(1, headSet.size()); - Iterator headSetIterator = headSet.iterator(); - assertEquals(new Integer(0).toString(), headSetIterator.next()); - assertFalse(headSetIterator.hasNext()); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.headSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - headSet = keySet.headSet(endKey, true); - assertEquals(2, headSet.size()); - headSetIterator = headSet.iterator(); - assertEquals(new Integer(0).toString(), headSetIterator.next()); - assertEquals(new Integer(1).toString(), headSetIterator.next()); - assertFalse(headSetIterator.hasNext()); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.headSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - try { - keySet.headSet(endKey, true).size(); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(101).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = ((NavigableMap) subMap_startExcluded_endIncluded_comparator) - .navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(101).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 101; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = ((NavigableMap) subMap_startIncluded_endExcluded_comparator) - .navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - endKey = new Integer(101).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(102, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = ((NavigableMap) subMap_startIncluded_endIncluded_comparator) - .navigableKeySet(); - endKey = new Integer(99).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - endKey = new Integer(100).toString(); - assertEquals(0, keySet.headSet(endKey).size()); - assertEquals(0, keySet.headSet(endKey, false).size()); - assertEquals(1, keySet.headSet(endKey, true).size()); - - endKey = new Integer(101).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(101, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(102, index); - - for (int i = 102; i < 109; i++) { - endKey = new Integer(i).toString(); - - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - int j; - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i, j); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (j = 100; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(i + 1, j); - } - - endKey = new Integer(109).toString(); - headSet = keySet.headSet(endKey); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, false); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - headSet = keySet.headSet(endKey, true); - iterator = headSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - endKey = new Integer(110).toString(); - try { - keySet.headSet(endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.headSet(endKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - key = new Integer(1).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next(); - endKey = (String) iterator.next(); - headSet = keySet.headSet(endKey, false); - assertEquals(1, headSet.size()); - headSetIterator = headSet.iterator(); - assertEquals(new Integer(0).toString(), headSetIterator.next()); - assertFalse(headSetIterator.hasNext()); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.headSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - headSet = keySet.headSet(endKey, true); - assertEquals(2, headSet.size()); - headSetIterator = headSet.iterator(); - assertEquals(new Integer(0).toString(), headSetIterator.next()); - assertEquals(new Integer(1).toString(), headSetIterator.next()); - assertFalse(headSetIterator.hasNext()); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.headSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - } - - public void test_AscendingSubMapKeySet_remove() { - TreeMap tm_rm = new TreeMap(tm); - SortedMap subMap_startExcluded_endExcluded_rm = tm_rm.subMap( - objArray[100].toString(), false, objArray[109].toString(), - false); - assertNull(subMap_startExcluded_endExcluded_rm.remove("0")); - try { - subMap_startExcluded_endExcluded_rm.remove(null); - fail("should throw NPE"); - } catch (Exception e) { - // Expected - } - for (int i = 101; i < 108; i++) { - assertNotNull(subMap_startExcluded_endExcluded_rm - .remove(new Integer(i).toString())); - } - } - - public void test_AscendingSubMapKeySet_tailSet() { - NavigableSet keySet; - SortedSet tailSet; - String startKey, key; - Iterator iterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - int index; - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; index < 109; index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - - startKey = new Integer(101).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(108, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(108, j); - } - - startKey = new Integer(109).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(109, j); - } - - startKey = new Integer(109).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(108, index); - - startKey = new Integer(101).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(108, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(108, j); - } - - startKey = new Integer(109).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - startKey = new Integer(100).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(101).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(109, j); - } - - startKey = new Integer(109).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - String endKey = new Integer(1).toString(); - keySet = tm.headMap(endKey, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next(); - startKey = (String) iterator.next(); - tailSet = keySet.tailSet(startKey); - assertEquals(1, tailSet.size()); - Iterator tailSetIterator = tailSet.iterator(); - assertEquals(endKey, tailSetIterator.next()); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.tailSet(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - tailSet = keySet.tailSet(startKey, true); - assertEquals(1, tailSet.size()); - tailSetIterator = tailSet.iterator(); - assertEquals(endKey, tailSetIterator.next()); - - tailSet = keySet.tailSet(startKey, false); - assertEquals(0, tailSet.size()); - tailSetIterator = tailSet.iterator(); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - try { - keySet.tailSet(null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - try { - keySet.tailSet(null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; index < 109; index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - - startKey = new Integer(101).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(109, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 101; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(108, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(109, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(108, j); - } - - startKey = new Integer(109).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - startKey = new Integer(99).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - startKey = new Integer(100).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 100; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - for (int i = 102; i < 109; i++) { - startKey = new Integer(i).toString(); - - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - int j; - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j).toString(), key); - } - assertEquals(110, j); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (j = i; iterator.hasNext(); j++) { - key = (String) iterator.next(); - assertEquals(new Integer(j + 1).toString(), key); - } - assertEquals(109, j); - } - - startKey = new Integer(109).toString(); - tailSet = keySet.tailSet(startKey); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, true); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index).toString(), key); - } - assertEquals(110, index); - - tailSet = keySet.tailSet(startKey, false); - iterator = tailSet.iterator(); - for (index = 109; iterator.hasNext(); index++) { - key = (String) iterator.next(); - assertEquals(new Integer(index + 1).toString(), key); - } - assertEquals(109, index); - - startKey = new Integer(110).toString(); - try { - keySet.tailSet(startKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - try { - keySet.tailSet(startKey, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } - - public void test_AscendingSubMapKeySet_subSet() { - NavigableSet keySet; - SortedSet subSet; - String startKey, endKey, key; - Iterator startIterator, endIterator, subSetIterator; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - startIterator = keySet.iterator(); - while (startIterator.hasNext()) { - startKey = (String) startIterator.next(); - endIterator = keySet.iterator(); - while (endIterator.hasNext()) { - endKey = (String) endIterator.next(); - int startIndex = Integer.valueOf(startKey); - int endIndex = Integer.valueOf(endKey); - if (startIndex > endIndex) { - try { - keySet.subSet(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = keySet.subSet(startKey, endKey); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, false, endKey, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, false, endKey, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, true, endKey, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, true, endKey, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - } - } - } - - key = new Integer(1).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - Iterator iterator = keySet.iterator(); - startKey = (String) iterator.next(); - endKey = (String) iterator.next(); - - subSet = keySet.subSet(startKey, endKey); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, false, endKey, false); - assertEquals(0, subSet.size()); - - subSet = keySet.subSet(startKey, false, endKey, true); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(1).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, true, endKey, false); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, true, endKey, true); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - assertEquals(new Integer(1).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - keySet.subSet(null, null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, endKey); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, endKey, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, endKey, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, endKey, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, endKey, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - // With Comparator - keySet = ((NavigableMap) subMap_startExcluded_endExcluded_comparator) - .navigableKeySet(); - startIterator = keySet.iterator(); - while (startIterator.hasNext()) { - startKey = (String) startIterator.next(); - endIterator = keySet.iterator(); - while (endIterator.hasNext()) { - endKey = (String) endIterator.next(); - int startIndex = Integer.valueOf(startKey); - int endIndex = Integer.valueOf(endKey); - if (startIndex > endIndex) { - try { - keySet.subSet(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, endKey, false); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, endKey, true); - fail("shoudl throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = keySet.subSet(startKey, endKey); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, false, endKey, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, false, endKey, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, true, endKey, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - - subSet = keySet.subSet(startKey, true, endKey, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(new Integer(index).toString(), - subSetIterator.next()); - } - } - } - } - - key = new Integer(1).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - startKey = (String) iterator.next(); - endKey = (String) iterator.next(); - - subSet = keySet.subSet(startKey, endKey); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, false, endKey, false); - assertEquals(0, subSet.size()); - - subSet = keySet.subSet(startKey, false, endKey, true); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(1).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, true, endKey, false); - assertEquals(1, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - subSet = keySet.subSet(startKey, true, endKey, true); - assertEquals(2, subSet.size()); - subSetIterator = subSet.iterator(); - assertEquals(new Integer(0).toString(), subSetIterator.next()); - assertEquals(new Integer(1).toString(), subSetIterator.next()); - try { - subSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - try { - keySet.subSet(null, null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, endKey); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, endKey, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, false, endKey, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, endKey, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(null, true, endKey, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, false, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, null, false); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - try { - keySet.subSet(startKey, true, null, true); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - } - - public void test_AscendingSubMapKeySet_lower() { - NavigableSet keySet; - Iterator iterator; - String key, lowerKey; - int value, lowerValue; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.lower(key); - if (value > 101) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value - 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.lower(key); - if (value > 101) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value - 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.lower(key); - if (value > 100) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value - 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.lower(key); - if (value > 100) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value - 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next();// 0 - String expectedLowerKey = (String) iterator.next();// 1 - assertEquals(expectedLowerKey, keySet.lower(iterator.next())); - - try { - keySet.lower(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNull(keySet.lower(key)); - - key = new Integer(0).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.lower(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNotNull(keySet.lower(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNotNull(keySet.lower(key)); - } - - public void test_AscendingSubMapKeySet_higher() { - NavigableSet keySet; - Iterator iterator; - String key, lowerKey; - int value, lowerValue; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.higher(key); - if (value < 108) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.higher(key); - if (value < 109) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.higher(key); - if (value < 108) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - iterator = keySet.iterator(); - while (iterator.hasNext()) { - key = (String) iterator.next(); - value = Integer.valueOf(key); - lowerKey = (String) keySet.higher(key); - if (value < 109) { - lowerValue = Integer.valueOf(lowerKey); - assertEquals(value + 1, lowerValue); - } else { - assertNull(lowerKey); - } - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - iterator = keySet.iterator(); - iterator.next();// 0 - iterator.next();// 1 - lowerKey = (String) keySet.higher(iterator.next()); - String expectedLowerKey = (String) iterator.next(); - assertEquals(expectedLowerKey, lowerKey); - - try { - keySet.higher(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(0).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.higher(key)); - } - - public void test_AscendingSubMapKeySet_ceiling() { - NavigableSet keySet; - String key; - String[] keyArray; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 101; i < keyArray.length; i++) { - key = (String) keySet.ceiling(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 101; i < keyArray.length; i++) { - key = (String) keySet.ceiling(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 100; i < keyArray.length; i++) { - key = (String) keySet.ceiling(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 100; i < keyArray.length; i++) { - key = (String) keySet.ceiling(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - Iterator iterator = keySet.iterator(); - iterator.next(); - assertEquals(new Integer(1).toString(), keySet.ceiling(iterator.next())); - - try { - keySet.ceiling(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertEquals(key, keySet.ceiling(key)); - - key = new Integer(0).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertNull(keySet.higher(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.higher(key)); - } - - public void test_AscendingSubMapKeySet_floor() { - NavigableSet keySet; - String key; - String[] keyArray; - - keySet = navigableMap_startExcluded_endExcluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 101; i < keyArray.length; i++) { - key = (String) keySet.floor(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startExcluded_endIncluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 101; i < keyArray.length; i++) { - key = (String) keySet.floor(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startIncluded_endExcluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 100; i < keyArray.length; i++) { - key = (String) keySet.floor(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - keySet = navigableMap_startIncluded_endIncluded.navigableKeySet(); - keyArray = (String[]) keySet.toArray(new String[keySet.size()]); - for (int i = 0, j = 100; i < keyArray.length; i++) { - key = (String) keySet.floor(keyArray[i]); - assertEquals(new Integer(i + j).toString(), key); - } - - key = new Integer(2).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - Iterator iterator = keySet.iterator(); - iterator.next(); - assertEquals(new Integer(1).toString(), keySet.floor(iterator.next())); - - try { - keySet.floor(null); - fail("should throw NPE"); - } catch (NullPointerException e) { - // Expected - } - - key = new Integer(0).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertEquals(key, keySet.floor(key)); - - key = new Integer(0).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertNull(keySet.floor(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, true).navigableKeySet(); - assertEquals(key, keySet.floor(key)); - - key = new Integer(999).toString(); - keySet = tm.headMap(key, false).navigableKeySet(); - assertEquals(new Integer(998).toString(), keySet.floor(key)); - } - - public void test_BoundedEntryIterator_next() { - Iterator iterator = subMap_default.entrySet().iterator(); - assertTrue(iterator.hasNext()); - for (int i = 100; iterator.hasNext(); i++) { - assertEquals(i, ((Entry) iterator.next()).getValue()); - } - - try { - iterator.next(); - fail("should throw java.util.NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - } - - public void test_BoundedKeyIterator_next() { - Iterator iterator = subMap_default.keySet().iterator(); - assertTrue(iterator.hasNext()); - for (int i = 100; iterator.hasNext(); i++) { - assertEquals(new Integer(i).toString(), iterator.next()); - } - - try { - iterator.next(); - fail("should throw java.util.NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - public void test_BoundedValueIterator_next() { - String startKey = new Integer(101).toString(); - String endKey = new Integer(108).toString(); - - Collection values = tm.subMap(startKey, endKey).values(); - Iterator iter = values.iterator(); - for (int i = 101; i < 108; i++) { - assertEquals(i, iter.next()); - } - try { - iter.next(); - fail("should throw java.util.NoSuchElementException"); - } catch (Exception e) { - // Expected - } - } - - /* - * SubMapEntrySet - */ - public void test_SubMapEntrySet_Constructor() { - } - - public void test_SubMapEntrySet_contains() { - // covered in test_SubMapEntrySet_remove - } - - public void test_SubMapEntrySet_iterator() { - Set entrySet = subMap_default.entrySet(); - Iterator iterator; - Entry entry; - Integer value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startExcluded_endExcluded.entrySet(); - value = new Integer(101); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startExcluded_endIncluded.entrySet(); - value = new Integer(101); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(110, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startIncluded_endExcluded.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startIncluded_endIncluded.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(110, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - String startKey = new Integer(-1).toString(); - String endKey = new Integer(0).toString(); - SortedMap subMap = tm.subMap(startKey, endKey); - entrySet = subMap.entrySet(); - iterator = entrySet.iterator(); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - entrySet = subMap.entrySet(); - iterator = entrySet.iterator(); - assertEquals(0, ((Entry) iterator.next()).getValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - endKey = new Integer(2000).toString(); - subMap = tm.subMap(startKey, endKey); - entrySet = subMap.entrySet(); - iterator = entrySet.iterator(); - for (int i = 0; i < subMap.size(); i++) { - iterator.next(); - } - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - startKey = new Integer(9).toString(); - endKey = new Integer(100).toString(); - try { - tm.subMap(startKey, endKey); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - // With Comparator - entrySet = subMap_default_comparator.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - value = new Integer(101); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - value = new Integer(101); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(110, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(109, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - entrySet = subMap_startIncluded_endIncluded_comparator.entrySet(); - value = new Integer(100); - for (iterator = entrySet.iterator(); iterator.hasNext(); value++) { - entry = (Entry) iterator.next(); - assertEquals(value.toString(), entry.getKey()); - assertEquals(value, entry.getValue()); - } - assertEquals(110, value.intValue()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - public void test_SubMapEntrySet_remove() { - Set entrySet = subMap_default.entrySet(); - assertFalse(entrySet.remove(null)); - int size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - - entrySet = subMap_startExcluded_endExcluded.entrySet(); - assertFalse(entrySet.remove(null)); - size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - - entrySet = subMap_startExcluded_endIncluded.entrySet(); - assertFalse(entrySet.remove(null)); - size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - - entrySet = subMap_startIncluded_endExcluded.entrySet(); - assertFalse(entrySet.remove(null)); - size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - - entrySet = subMap_startIncluded_endIncluded.entrySet(); - assertFalse(entrySet.remove(null)); - size = entrySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = entrySet.iterator(); - assertTrue(entrySet.remove(iterator.next())); - } - } - - public void test_SubMapEntrySet_isEmpty() { - assertFalse(subMap_default.entrySet().isEmpty()); - assertFalse(subMap_startExcluded_endExcluded.entrySet().isEmpty()); - assertFalse(subMap_startExcluded_endIncluded.entrySet().isEmpty()); - assertFalse(subMap_startIncluded_endExcluded.entrySet().isEmpty()); - assertFalse(subMap_startIncluded_endIncluded.entrySet().isEmpty()); - - String startKey = new Integer(0).toString(); - String endKey = startKey; - SortedMap subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.entrySet().isEmpty()); - - startKey = new Integer(-1).toString(); - subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.entrySet().isEmpty()); - - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - assertFalse(subMap.entrySet().isEmpty()); - } - - public void test_SubMapEntrySet_size() { - assertEquals(9, subMap_default.entrySet().size()); - assertEquals(8, subMap_startExcluded_endExcluded.entrySet().size()); - assertEquals(9, subMap_startExcluded_endIncluded.entrySet().size()); - assertEquals(9, subMap_startIncluded_endExcluded.entrySet().size()); - assertEquals(10, subMap_startIncluded_endIncluded.entrySet().size()); - - String startKey = new Integer(0).toString(); - String endKey = new Integer(2).toString(); - SortedMap subMap = tm.subMap(startKey, endKey); - assertEquals(112, subMap.entrySet().size()); - - startKey = new Integer(0).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.entrySet().size()); - - startKey = new Integer(-1).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.entrySet().size()); - - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - assertEquals(1, subMap.entrySet().size()); - - startKey = new Integer(999).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.entrySet().size()); - } - - /* - * SubMapKeySet - */ - public void test_SubMapKeySet_Constructor() { - // covered in other test - } - - public void test_SubMapKeySet_iterator() { - Set keySet = subMap_default.keySet(); - Iterator iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startExcluded_endExcluded.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(101 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startExcluded_endIncluded.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(101 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startIncluded_endExcluded.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startIncluded_endIncluded.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - // With Comparator - keySet = subMap_default_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startExcluded_endExcluded_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(101 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startExcluded_endIncluded_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(101 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startIncluded_endExcluded_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - keySet = subMap_startIncluded_endIncluded_comparator.keySet(); - iterator = keySet.iterator(); - for (int i = 0; i < keySet.size(); i++) { - assertEquals(new Integer(100 + i).toString(), iterator.next()); - } - assertFalse(iterator.hasNext()); - try { - iterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - - public void test_SubMapKeySet_isEmpty() { - assertFalse(subMap_default.keySet().isEmpty()); - assertFalse(subMap_startExcluded_endExcluded.keySet().isEmpty()); - assertFalse(subMap_startExcluded_endIncluded.keySet().isEmpty()); - assertFalse(subMap_startIncluded_endExcluded.keySet().isEmpty()); - assertFalse(subMap_startIncluded_endIncluded.keySet().isEmpty()); - - String startKey = new Integer(0).toString(); - String endKey = startKey; - SortedMap subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.keySet().isEmpty()); - - startKey = new Integer(999).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.keySet().isEmpty()); - - startKey = new Integer(-1).toString(); - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - assertFalse(subMap.keySet().isEmpty()); - - endKey = new Integer(0).toString(); - subMap = tm.subMap(startKey, endKey); - assertTrue(subMap.keySet().isEmpty()); - } - - public void test_SubMapKeySet_contains() { - Set keySet = subMap_default.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - String key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertTrue(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - - keySet = subMap_startExcluded_endExcluded.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertFalse(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - - keySet = subMap_startExcluded_endIncluded.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertFalse(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertTrue(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - - keySet = subMap_startIncluded_endExcluded.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertTrue(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - - keySet = subMap_startIncluded_endIncluded.keySet(); - try { - keySet.contains(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - key = new Integer(-1).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(99).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(100).toString(); - assertTrue(keySet.contains(key)); - for (int i = 101; i < 109; i++) { - key = new Integer(i).toString(); - assertTrue(keySet.contains(key)); - } - key = new Integer(109).toString(); - assertTrue(keySet.contains(key)); - key = new Integer(110).toString(); - assertFalse(keySet.contains(key)); - key = new Integer(1001).toString(); - assertFalse(keySet.contains(key)); - } - - public void test_SubMapKeySet_size() { - assertEquals(9, subMap_default.keySet().size()); - assertEquals(8, subMap_startExcluded_endExcluded.keySet().size()); - assertEquals(9, subMap_startExcluded_endIncluded.keySet().size()); - assertEquals(9, subMap_startIncluded_endExcluded.keySet().size()); - assertEquals(10, subMap_startIncluded_endIncluded.keySet().size()); - - String startKey = new Integer(0).toString(); - String endKey = new Integer(2).toString(); - SortedMap subMap = tm.subMap(startKey, endKey); - assertEquals(112, subMap.keySet().size()); - - startKey = new Integer(0).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.keySet().size()); - - startKey = new Integer(-1).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.keySet().size()); - - endKey = new Integer(1).toString(); - subMap = tm.subMap(startKey, endKey); - assertEquals(1, subMap.keySet().size()); - - startKey = new Integer(999).toString(); - endKey = startKey; - subMap = tm.subMap(startKey, endKey); - assertEquals(0, subMap.keySet().size()); - } - - public void test_SubMapKeySet_remove() { - Set keySet = subMap_default.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - int size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - - keySet = subMap_startExcluded_endExcluded.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - - keySet = subMap_startExcluded_endIncluded.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - - keySet = subMap_startIncluded_endExcluded.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - - keySet = subMap_startIncluded_endIncluded.keySet(); - try { - keySet.remove(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - size = keySet.size(); - for (int i = 0; i < size; i++) { - Iterator iterator = keySet.iterator(); - assertTrue(keySet.remove(iterator.next())); - } - } - - /* - * AscendingSubMapEntrySet - */ - - public void test_AscendingSubMapEntrySet_comparator() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - assertNull(ascendingSubMapEntrySet.comparator()); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - assertNull(ascendingSubMapEntrySet.comparator()); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - assertNull(ascendingSubMapEntrySet.comparator()); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - assertNull(ascendingSubMapEntrySet.comparator()); - } - } - - public void test_AscendingSubMapEntrySet_descendingSet() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet, descendingSet; - Entry entry; - int value; - Iterator iterator; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - iterator = descendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 108; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(100, value); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - iterator = descendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 109; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(100, value); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - iterator = descendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 108; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(99, value); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - descendingSet = ascendingSubMapEntrySet.descendingSet(); - iterator = descendingSet.iterator(); - assertTrue(iterator.hasNext()); - for (value = 109; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(99, value); - } - } - - public void test_AscendingSubMapEntrySet_descendingIterator() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - Entry entry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - for (value = 108; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(100, value); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - for (value = 109; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(100, value); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - for (value = 108; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(99, value); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - for (value = 109; iterator.hasNext(); value--) { - entry = (Entry) iterator.next(); - assertEquals(value, entry.getValue()); - } - assertEquals(99, value); - } - - String startKey = new Integer(2).toString(); - entrySet = tm.headMap(startKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.descendingIterator(); - assertTrue(iterator.hasNext()); - assertEquals(2, ((Entry) iterator.next()).getValue()); - } - } - - public void test_AscendingSubMapEntrySet_pollFirst_startExcluded_endExcluded() { - Set entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 101; value < 109; value++) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty. - assertNull(ascendingSubMapEntrySet.pollFirst()); - } - } - - public void test_AscendingSubMapEntrySet_pollFirst_startExcluded_endIncluded() { - Set entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 101; value < 110; value++) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty. - assertNull(ascendingSubMapEntrySet.pollFirst()); - } - } - - public void test_AscendingSubMapEntrySet_pollFirst_startIncluded_endExcluded() { - Set entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 100; value < 109; value++) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty. - assertNull(ascendingSubMapEntrySet.pollFirst()); - } - } - - public void test_AscendingSubMapEntrySet_pollFirst_startIncluded_endIncluded() { - Set entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 100; value < 110; value++) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollFirst(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty. - assertNull(ascendingSubMapEntrySet.pollFirst()); - } - } - - public void test_AscendingSubMapEntrySet_pollLast_startExcluded_endExcluded() { - Set entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 108; value > 100; value--) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollLast(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty - assertNull(ascendingSubMapEntrySet.pollLast()); - } - - // NavigableMap ascendingSubMap = tm.headMap("2", true); - // Set entrySet = ascendingSubMap.entrySet(); - // Object last; - // if (entrySet instanceof NavigableSet) { - // last = ((NavigableSet) entrySet).pollLast(); - // assertEquals("2=2", last.toString()); - // } - // - // ascendingSubMap = tm.tailMap("2", true); - // entrySet = ascendingSubMap.entrySet(); - // if (entrySet instanceof NavigableSet) { - // last = ((NavigableSet) entrySet).pollLast(); - // assertEquals("999=999", last.toString()); - // } - } - - public void test_AscendingSubMapEntrySet_pollLast_startExcluded_endIncluded() { - Set entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 109; value > 100; value--) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollLast(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty - assertNull(ascendingSubMapEntrySet.pollLast()); - } - } - - public void test_AscendingSubMapEntrySet_pollLast_startIncluded_endExcluded() { - Set entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 108; value > 99; value--) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollLast(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty - assertNull(ascendingSubMapEntrySet.pollLast()); - } - } - - public void test_AscendingSubMapEntrySet_pollLast_startIncluded_endIncluded() { - Set entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - NavigableSet ascendingSubMapEntrySet = (NavigableSet) entrySet; - for (int value = 109; value > 99; value--) { - Entry entry = (Entry) ascendingSubMapEntrySet.pollLast(); - assertEquals(value, entry.getValue()); - } - assertTrue(ascendingSubMapEntrySet.isEmpty()); - // should return null if the set is empty - assertNull(ascendingSubMapEntrySet.pollLast()); - } - } - - public void test_AscendingSubMapEntrySet_headSet() { - Set entrySet, headSet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator, headSetIterator; - Entry entry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = ascendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value - 1); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = ascendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 101; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value - 1); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = ascendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value - 1); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - headSet = ascendingSubMapEntrySet.headSet(entry); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, false); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - headSet = ascendingSubMapEntrySet.headSet(entry, true); - headSetIterator = headSet.iterator(); - for (value = 100; headSetIterator.hasNext(); value++) { - assertEquals(value, ((Entry) headSetIterator.next()) - .getValue()); - } - assertEquals(entry.getValue(), value - 1); - try { - headSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - // NavigableMap ascendingSubMap = tm.headMap("1", true); - // entrySet = ascendingSubMap.entrySet(); - // if (entrySet instanceof SortedSet) { - // Iterator it = entrySet.iterator(); - // it.next(); - // Object end = it.next();// 1=1 - // Set headSet = ((NavigableSet) entrySet).headSet(end);// inclusive - // // false - // assertEquals(1, headSet.size()); - // } - } - - public void test_AscendingSubMapEntrySet_tailSet() { - Set entrySet, tailSet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator, tailSetIterator; - Entry entry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = ascendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = ascendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = ascendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(109, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - tailSet = ascendingSubMapEntrySet.tailSet(entry); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, false); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue() + 1; tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - - tailSet = ascendingSubMapEntrySet.tailSet(entry, true); - tailSetIterator = tailSet.iterator(); - for (value = (Integer) entry.getValue(); tailSetIterator - .hasNext(); value++) { - assertEquals(value, ((Entry) tailSetIterator.next()) - .getValue()); - } - assertEquals(110, value); - try { - tailSetIterator.next(); - fail("should throw NoSuchElementException"); - } catch (NoSuchElementException e) { - // Expected - } - } - } - - // NavigableMap ascendingSubMap = tm.headMap("1", true); - // Set entrySet = ascendingSubMap.entrySet(); - // if (entrySet instanceof NavigableSet) { - // Iterator it = entrySet.iterator(); - // Object start = it.next();// 0=0 - // Set tailSet = ((NavigableSet) entrySet).tailSet(start);// default - // // inclusive - // // false - // assertEquals(1, tailSet.size()); - // } - } - - public void test_AscendingSubMapEntrySet_subSet() { - Set entrySet, subSet; - NavigableSet ascendingSubMapEntrySet; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - Iterator iteratorStart = ascendingSubMapEntrySet.iterator(); - while (iteratorStart.hasNext()) { - Entry startEntry = (Entry) iteratorStart.next(); - Iterator iteratorEnd = ascendingSubMapEntrySet.iterator(); - while (iteratorEnd.hasNext()) { - Entry endEntry = (Entry) iteratorEnd.next(); - int startIndex = (Integer) startEntry.getValue(); - int endIndex = (Integer) endEntry.getValue(); - if (startIndex > endIndex) { - try { - ascendingSubMapEntrySet - .subSet(startEntry, endEntry); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - ascendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - ascendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - ascendingSubMapEntrySet.subSet(startEntry, true, - endEntry, false); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - - try { - ascendingSubMapEntrySet.subSet(startEntry, true, - endEntry, true); - fail("should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected - } - } else { - subSet = ascendingSubMapEntrySet.subSet(startEntry, - endEntry); - Iterator subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator - .hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = ascendingSubMapEntrySet.subSet(startEntry, - false, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator - .hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = ascendingSubMapEntrySet.subSet(startEntry, - false, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex + 1; subSetIterator - .hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = ascendingSubMapEntrySet.subSet(startEntry, - true, endEntry, false); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - - subSet = ascendingSubMapEntrySet.subSet(startEntry, - true, endEntry, true); - subSetIterator = subSet.iterator(); - for (int index = startIndex; subSetIterator.hasNext(); index++) { - assertEquals(index, ((Entry) subSetIterator.next()) - .getValue()); - } - } - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - Iterator iterator = entrySet.iterator(); - Object startEntry = iterator.next(); - iterator.next(); - Object endEntry = iterator.next(); - subSet = ascendingSubMapEntrySet.subSet(startEntry, endEntry); - assertEquals(1, subSet.size()); - - subSet = ascendingSubMapEntrySet.subSet(startEntry, false, - endEntry, false); - assertEquals(1, subSet.size()); - - subSet = ascendingSubMapEntrySet.subSet(startEntry, false, - endEntry, true); - assertEquals(2, subSet.size()); - - subSet = ascendingSubMapEntrySet.subSet(startEntry, true, endEntry, - false); - assertEquals(2, subSet.size()); - - subSet = ascendingSubMapEntrySet.subSet(startEntry, true, endEntry, - true); - assertEquals(3, subSet.size()); - } - } - - public void test_AscendingSubMapEntrySet_lower() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - Entry entry, lowerEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - Entry expectedEntry = (Entry) iterator.next(); - entry = (Entry) iterator.next(); - assertEquals(expectedEntry, ascendingSubMapEntrySet.lower(entry)); - } - - // With Comparator - - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 101) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startIncluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.lower(entry); - value = (Integer) entry.getValue(); - if (value > 100) { - assertEquals(value - 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - } - - public void test_AscendingSubMapEntrySet_higher() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - Entry entry, lowerEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - String endKey = new Integer(2).toString(); - entrySet = tm.headMap(endKey, true).entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = entrySet.iterator(); - entry = (Entry) iterator.next(); - Entry expectedEntry = (Entry) iterator.next(); - assertEquals(expectedEntry, ascendingSubMapEntrySet.higher(entry)); - } - - // With Comparator - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 108) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - - entrySet = subMap_startIncluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.higher(entry); - value = (Integer) entry.getValue(); - if (value < 109) { - assertEquals(value + 1, lowerEntry.getValue()); - } else { - assertNull(lowerEntry); - } - } - } - } - - public void test_AscendingSubMapEntrySet_ceiling() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - - Set entrySet_beyondBound; - Iterator iterator_beyondBound; - Entry beyondBoundEntry; - - Entry entry, lowerEntry; - int value = 0; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(108, value); - - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(109, value); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(108, value); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(109, value); - } - - // With Comparator - entrySet = subMap_startIncluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(109, value); - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(108, value); - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(109, value); - } - - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.ceiling(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - while (iterator.hasNext()) { - entry = (Entry) iterator.next(); - lowerEntry = (Entry) ascendingSubMapEntrySet.ceiling(entry); - value = (Integer) entry.getValue(); - assertEquals(value, lowerEntry.getValue()); - } - assertEquals(108, value); - } - } - - public void test_AscendingSubMapEntrySet_floor() { - Set entrySet; - NavigableSet ascendingSubMapEntrySet; - Iterator iterator; - Entry entry, floorEntry; - int value; - - entrySet = navigableMap_startExcluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 101; i < 109; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = navigableMap_startExcluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 101; i < 110; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = navigableMap_startIncluded_endExcluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 100; i < 109; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = navigableMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 100; i < 110; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - // With Comparator - entrySet = subMap_startExcluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 101; i < 109; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = subMap_startExcluded_endIncluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 101; i < 110; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = subMap_startIncluded_endExcluded_comparator.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 100; i < 109; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - - entrySet = subMap_startIncluded_endIncluded.entrySet(); - if (entrySet instanceof NavigableSet) { - ascendingSubMapEntrySet = (NavigableSet) entrySet; - try { - ascendingSubMapEntrySet.floor(null); - fail("should throw NullPointerException"); - } catch (NullPointerException e) { - // Expected - } - - iterator = ascendingSubMapEntrySet.iterator(); - for (int i = 100; i < 110; i++) { - entry = (Entry) iterator.next(); - floorEntry = (Entry) ascendingSubMapEntrySet.floor(entry); - assertEquals(entry.getValue(), floorEntry.getValue()); - } - assertFalse(iterator.hasNext()); - } - } - - @Override - protected void setUp() { - tm = new TreeMap(); - tm_comparator = new TreeMap(new MockComparator()); - for (int i = 0; i < objArray.length; i++) { - Object x = objArray[i] = new Integer(i); - tm.put(x.toString(), x); - tm_comparator.put(x.toString(), x); - } - - subMap_default = tm.subMap(objArray[100].toString(), objArray[109] - .toString()); - subMap_startExcluded_endExcluded = tm.subMap(objArray[100].toString(), - false, objArray[109].toString(), false); - subMap_startExcluded_endIncluded = tm.subMap(objArray[100].toString(), - false, objArray[109].toString(), true); - subMap_startIncluded_endExcluded = tm.subMap(objArray[100].toString(), - true, objArray[109].toString(), false); - subMap_startIncluded_endIncluded = tm.subMap(objArray[100].toString(), - true, objArray[109].toString(), true); - - subMap_default_beforeStart_100 = tm.subMap(objArray[0].toString(), - objArray[1].toString()); - - subMap_default_afterEnd_109 = tm.subMap(objArray[110].toString(), - objArray[119].toString()); - - assertTrue(subMap_startExcluded_endExcluded instanceof NavigableMap); - assertTrue(subMap_startExcluded_endIncluded instanceof NavigableMap); - assertTrue(subMap_startIncluded_endExcluded instanceof NavigableMap); - assertTrue(subMap_startIncluded_endIncluded instanceof NavigableMap); - - navigableMap_startExcluded_endExcluded = (NavigableMap) subMap_startExcluded_endExcluded; - navigableMap_startExcluded_endIncluded = (NavigableMap) subMap_startExcluded_endIncluded; - navigableMap_startIncluded_endExcluded = (NavigableMap) subMap_startIncluded_endExcluded; - navigableMap_startIncluded_endIncluded = (NavigableMap) subMap_startIncluded_endIncluded; - - subMap_default_comparator = tm_comparator.subMap(objArray[100] - .toString(), objArray[109].toString()); - subMap_startExcluded_endExcluded_comparator = tm_comparator.subMap( - objArray[100].toString(), false, objArray[109].toString(), - false); - - subMap_startExcluded_endIncluded_comparator = tm_comparator - .subMap(objArray[100].toString(), false, objArray[109] - .toString(), true); - subMap_startIncluded_endExcluded_comparator = tm_comparator - .subMap(objArray[100].toString(), true, objArray[109] - .toString(), false); - subMap_startIncluded_endIncluded_comparator = tm_comparator.subMap( - objArray[100].toString(), true, objArray[109].toString(), true); - } - - @Override - protected void tearDown() { - tm = null; - tm_comparator = null; - - subMap_default = null; - subMap_startExcluded_endExcluded = null; - subMap_startExcluded_endIncluded = null; - subMap_startIncluded_endExcluded = null; - subMap_startIncluded_endIncluded = null; - - subMap_default_beforeStart_100 = null; - subMap_default_afterEnd_109 = null; - - subMap_default_comparator = null; - subMap_startExcluded_endExcluded_comparator = null; - subMap_startExcluded_endIncluded_comparator = null; - subMap_startIncluded_endExcluded_comparator = null; - subMap_startIncluded_endIncluded_comparator = null; - } - - public void test_lower_null() throws Exception { - NavigableMap map = tm.subMap(objArray[100].toString(), true, - objArray[100].toString(), false); - assertNull(map.ceilingKey(objArray[100].toString())); - assertNull(map.floorKey(objArray[100].toString())); - assertNull(map.lowerKey(objArray[100].toString())); - assertNull(map.higherKey(objArray[100].toString())); - assertNull(map.ceilingKey(objArray[111].toString())); - assertNull(map.floorKey(objArray[111].toString())); - assertNull(map.lowerKey(objArray[111].toString())); - assertNull(map.higherKey(objArray[111].toString())); - assertNull(map.ceilingKey(objArray[1].toString())); - assertNull(map.floorKey(objArray[1].toString())); - assertNull(map.lowerKey(objArray[1].toString())); - assertNull(map.higherKey(objArray[1].toString())); - map = map.descendingMap(); - assertNull(map.ceilingKey(objArray[100].toString())); - assertNull(map.floorKey(objArray[100].toString())); - assertNull(map.lowerKey(objArray[100].toString())); - assertNull(map.higherKey(objArray[100].toString())); - assertNull(map.ceilingKey(objArray[111].toString())); - assertNull(map.floorKey(objArray[111].toString())); - assertNull(map.lowerKey(objArray[111].toString())); - assertNull(map.higherKey(objArray[111].toString())); - assertNull(map.ceilingKey(objArray[1].toString())); - assertNull(map.floorKey(objArray[1].toString())); - assertNull(map.lowerKey(objArray[1].toString())); - assertNull(map.higherKey(objArray[1].toString())); - } - - public void test_lower_tail() throws Exception { - NavigableMap map = tm.subMap(objArray[102].toString(), true, - objArray[103].toString(), false); - assertTrue(map.containsKey(objArray[102].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertFalse(map.containsKey(objArray[103].toString())); - assertFalse(map.containsKey(objArray[104].toString())); - map = map.descendingMap(); - assertTrue(map.containsKey(objArray[102].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertFalse(map.containsKey(objArray[103].toString())); - assertFalse(map.containsKey(objArray[104].toString())); - map = tm.subMap(objArray[102].toString(), true, objArray[102] - .toString(), false); - assertFalse(map.containsKey(objArray[102].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertFalse(map.containsKey(objArray[103].toString())); - assertFalse(map.containsKey(objArray[104].toString())); - map = map.descendingMap(); - assertFalse(map.containsKey(objArray[102].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertFalse(map.containsKey(objArray[103].toString())); - assertFalse(map.containsKey(objArray[104].toString())); - } - - public void test_contains_null() throws Exception { - NavigableMap map = tm.subMap(objArray[100].toString(), true, - objArray[100].toString(), false); - assertFalse(map.containsKey(objArray[100].toString())); - assertFalse(map.containsKey(objArray[10].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertFalse(map.containsKey(objArray[102].toString())); - assertFalse(map.containsKey(objArray[1].toString())); - map = map.descendingMap(); - assertFalse(map.containsKey(objArray[100].toString())); - assertFalse(map.containsKey(objArray[10].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertFalse(map.containsKey(objArray[102].toString())); - assertFalse(map.containsKey(objArray[1].toString())); - } - - public void test_contains() throws Exception { - NavigableMap map = tm.subMap(objArray[102].toString(), true, - objArray[103].toString(), false); - assertFalse(map.containsKey(objArray[100].toString())); - assertFalse(map.containsKey(objArray[104].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertTrue(map.containsKey(objArray[102].toString())); - map = map.descendingMap(); - assertFalse(map.containsKey(objArray[100].toString())); - assertFalse(map.containsKey(objArray[104].toString())); - assertFalse(map.containsKey(objArray[101].toString())); - assertTrue(map.containsKey(objArray[102].toString())); - } - - public void test_size() throws Exception { - NavigableMap map = tm.subMap(objArray[102].toString(), true, - objArray[103].toString(), false); - assertEquals(0, map.headMap(objArray[102].toString(), false).size()); - assertEquals(1, map.headMap(objArray[102].toString(), true).size()); - try { - assertEquals(1, map.headMap(objArray[103].toString(), true).size()); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - assertEquals(1, map.headMap(objArray[103].toString(), false).size()); - assertEquals(1, map.tailMap(objArray[102].toString(), true).size()); - assertEquals(0, map.tailMap(objArray[102].toString(), false).size()); - assertTrue(map.headMap(objArray[103].toString(), false).containsKey( - objArray[102].toString())); - try { - assertTrue(map.headMap(objArray[103].toString(), true).containsKey( - objArray[102].toString())); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - assertFalse(map.headMap(objArray[102].toString(), false).containsKey( - objArray[102].toString())); - assertTrue(map.headMap(objArray[102].toString(), true).containsKey( - objArray[102].toString())); - assertTrue(map.tailMap(objArray[102].toString(), true).containsKey( - objArray[102].toString())); - assertFalse(map.tailMap(objArray[102].toString(), true).containsKey( - objArray[103].toString())); - try { - assertEquals(0, map.tailMap(objArray[101].toString()).size()); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - map = map.descendingMap(); - try { - map = map.subMap(objArray[103].toString(), true, objArray[102] - .toString(), true); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - map = map.subMap(objArray[102].toString(), true, objArray[102] - .toString(), true); - assertEquals(1, map.headMap(objArray[102].toString(), true).size()); - assertEquals(0, map.headMap(objArray[102].toString(), false).size()); - try { - assertEquals(0, map.headMap(objArray[103].toString(), true).size()); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - - assertEquals(1, map.tailMap(objArray[102].toString(), true).size()); - try { - assertFalse(map.headMap(objArray[103].toString(), true) - .containsKey(objArray[102].toString())); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - assertTrue(map.headMap(objArray[102].toString(), true).containsKey( - objArray[102].toString())); - assertFalse(map.headMap(objArray[102].toString(), false).containsKey( - objArray[102].toString())); - assertTrue(map.tailMap(objArray[102].toString(), true).containsKey( - objArray[102].toString())); - assertFalse(map.tailMap(objArray[102].toString(), true).containsKey( - objArray[103].toString())); - try { - assertEquals(0, map.tailMap(objArray[101].toString()).size()); - fail("should throw IAE"); - } catch (IllegalArgumentException e) { - } - } - - public void test_lower() throws Exception { - NavigableMap map = tm.subMap(objArray[102].toString(), true, - objArray[103].toString(), false); - assertEquals(objArray[102].toString(), map.higherKey(objArray[101] - .toString())); - assertEquals(null, map.higherKey(objArray[102].toString())); - assertEquals(null, map.higherKey(objArray[103].toString())); - assertEquals(null, map.higherKey(objArray[104].toString())); - assertEquals(objArray[102].toString(), map.ceilingKey(objArray[101] - .toString())); - assertEquals(objArray[102].toString(), map.ceilingKey(objArray[102] - .toString())); - assertEquals(null, map.ceilingKey(objArray[103].toString())); - assertEquals(null, map.ceilingKey(objArray[104].toString())); - assertEquals(null, map.lowerKey(objArray[101].toString())); - assertEquals(null, map.lowerKey(objArray[102].toString())); - assertEquals(objArray[102].toString(), map.lowerKey(objArray[103] - .toString())); - assertEquals(objArray[102].toString(), map.lowerKey(objArray[104] - .toString())); - assertEquals(null, map.floorKey(objArray[101].toString())); - assertEquals(objArray[102].toString(), map.floorKey(objArray[102] - .toString())); - assertEquals(objArray[102].toString(), map.floorKey(objArray[103] - .toString())); - assertEquals(objArray[102].toString(), map.floorKey(objArray[104] - .toString())); - map = map.descendingMap(); - assertEquals(null, map.higherKey(objArray[101].toString())); - assertEquals(null, map.higherKey(objArray[102].toString())); - assertEquals(objArray[102].toString(), map.higherKey(objArray[103] - .toString())); - assertEquals(objArray[102].toString(), map.higherKey(objArray[104] - .toString())); - assertEquals(null, map.ceilingKey(objArray[101].toString())); - assertEquals(objArray[102].toString(), map.ceilingKey(objArray[102] - .toString())); - assertEquals(objArray[102].toString(), map.ceilingKey(objArray[103] - .toString())); - assertEquals(objArray[102].toString(), map.ceilingKey(objArray[104] - .toString())); - assertEquals(objArray[102].toString(), map.lowerKey(objArray[101] - .toString())); - assertEquals(null, map.lowerKey(objArray[102].toString())); - assertEquals(null, map.lowerKey(objArray[103].toString())); - assertEquals(null, map.lowerKey(objArray[104].toString())); - assertEquals(objArray[102].toString(), map.floorKey(objArray[101] - .toString())); - assertEquals(objArray[102].toString(), map.floorKey(objArray[102] - .toString())); - assertEquals(null, map.floorKey(objArray[103].toString())); - assertEquals(null, map.floorKey(objArray[104].toString())); - } - - public void test_lowerkey() throws Exception { - try { - tm.subMap(objArray[100].toString(), true, objArray[100].toString(), - false).descendingMap().firstKey(); - fail("should throw NoSuchElementException"); - } catch (Exception e) { - // expected - } - try { - tm.subMap(objArray[100].toString(), true, objArray[100].toString(), - false).descendingMap().lastKey(); - fail("should throw NoSuchElementException"); - } catch (Exception e) { - // expected - } - try { - tm.subMap(objArray[100].toString(), true, objArray[100].toString(), - false).firstKey(); - fail("should throw NoSuchElementException"); - } catch (Exception e) { - // expected - } - try { - tm.subMap(objArray[100].toString(), true, objArray[100].toString(), - false).lastKey(); - fail("should throw NoSuchElementException"); - } catch (Exception e) { - // expected - } - - } - - public void test_headMap() throws Exception { - TreeMap tree = new TreeMap(); - tree.put(new Integer(0), null); - tree.put(new Integer(1), null); - Map submap = tree.subMap(tree.firstKey(), tree.lastKey()); - tree.remove(tree.lastKey()); - assertEquals(submap, tree); - } - - public void testname() throws Exception { - TreeMap nullTree = new TreeMap(new Comparator() { - public int compare(Object o1, Object o2) { - if (o1 == null) { - return o2 == null ? 0 : -1; - } - return ((String) o1).compareTo((String) o2); - } - }); - nullTree.put(new String("One"), 1); - nullTree.put(new String("Two"), 2); - nullTree.put(new String("Three"), 3); - nullTree.put(new String("Four"), 4); - nullTree.put(null, 0); - nullTree.subMap(null, "two").size(); - } - -} diff --git a/src/test/java/org/mapdb/TxEngineTest.java b/src/test/java/org/mapdb/TxEngineTest.java deleted file mode 100644 index 511b43e88..000000000 --- a/src/test/java/org/mapdb/TxEngineTest.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.mapdb; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Map; - -import static org.junit.Assert.*; - -public class TxEngineTest { - - TxEngine e; - - - @Before public void init(){ - e = new TxEngine(new StoreWAL(null),false); - } - - @Test public void update(){ - long recid = e.put(111, Serializer.INTEGER); - e.commit(); - Engine snapshot = e.snapshot(); - e.update(recid, 222, Serializer.INTEGER); - assertEquals(Integer.valueOf(111), snapshot.get(recid, Serializer.INTEGER)); - } - - @Test public void compareAndSwap(){ - long recid = e.put(111, Serializer.INTEGER); - e.commit(); - Engine snapshot = e.snapshot(); - e.compareAndSwap(recid, 111, 222, Serializer.INTEGER); - assertEquals(Integer.valueOf(111), snapshot.get(recid, Serializer.INTEGER)); - } - - @Test public void delete(){ - long recid = e.put(111, Serializer.INTEGER); - e.commit(); - Engine snapshot = e.snapshot(); - e.delete(recid, Serializer.INTEGER); - assertEquals(Integer.valueOf(111), snapshot.get(recid, Serializer.INTEGER)); - } - - @Test public void notExist(){ - Engine snapshot = e.snapshot(); - long recid = e.put(111, Serializer.INTEGER); - assertNull(snapshot.get(recid, Serializer.INTEGER)); - } - - - @Test public void create_snapshot(){ - Engine e = DBMaker.newMemoryDB().snapshotEnable().makeEngine(); - Engine snapshot = TxEngine.createSnapshotFor(e); - assertNotNull(snapshot); - } - - @Test public void DB_snapshot(){ - DB db = DBMaker.newMemoryDB().snapshotEnable().asyncWriteFlushDelay(100).transactionDisable().make(); - long recid = db.getEngine().put("aa", Serializer.STRING_NOSIZE); - DB db2 = db.snapshot(); - assertEquals("aa", db2.getEngine().get(recid,Serializer.STRING_NOSIZE)); - db.getEngine().update(recid, "bb",Serializer.STRING_NOSIZE); - assertEquals("aa", db2.getEngine().get(recid, Serializer.STRING_NOSIZE)); - } - - @Test public void DB_snapshot2(){ - DB db = DBMaker.newMemoryDB().transactionDisable().snapshotEnable().make(); - long recid = db.getEngine().put("aa",Serializer.STRING_NOSIZE); - DB db2 = db.snapshot(); - assertEquals("aa", db2.getEngine().get(recid,Serializer.STRING_NOSIZE)); - db.getEngine().update(recid, "bb",Serializer.STRING_NOSIZE); - assertEquals("aa", db2.getEngine().get(recid,Serializer.STRING_NOSIZE)); - } - - - @Test public void BTreeMap_snapshot(){ - BTreeMap map = - DBMaker.newMemoryDB().transactionDisable().snapshotEnable() - .make().getTreeMap("aaa"); - map.put("aa","aa"); - Map map2 = map.snapshot(); - map.put("aa","bb"); - assertEquals("aa",map2.get("aa")); - } - - @Test public void HTreeMap_snapshot(){ - HTreeMap map = - DBMaker.newMemoryDB().transactionDisable().snapshotEnable() - .make().getHashMap("aaa"); - map.put("aa","aa"); - Map map2 = map.snapshot(); - map.put("aa", "bb"); - assertEquals("aa",map2.get("aa")); - } - -// @Test public void test_stress(){ -// ExecutorService ex = Executors.newCachedThreadPool(); -// -// TxMaker tx = DBMaker.newMemoryDB().transactionDisable().makeTxMaker(); -// -// DB db = tx.makeTx(); -// final long recid = -// -// final int threadNum = 32; -// for(int i=0;i ex = new CopyOnWriteArrayList(); - final Collection s = Collections.synchronizedCollection(new HashSet()); - for(int i=0;i queue = db.getQueue(index + ""); -// queue.offer(temp + ""); - Map map = db.getHashMap("ha"); - if(temp!=t) - assertEquals(temp-1,map.get(temp-1)); - map.put(temp, temp ); - } - }); - } - }catch(Throwable e){ - e.printStackTrace(); - ex.add(e); - }finally{ - l.countDown(); - } - } - }.start(); - } - while(!l.await(100, TimeUnit.MILLISECONDS) && ex.isEmpty()){} - - if(!ex.isEmpty()) - throw ex.get(0); - - Map m = tx.makeTx().getHashMap("ha"); - assertEquals(s.size(),m.size()); - for(Object i:s){ - assertEquals(i, m.get(i)); - } - - } - - - @Test(timeout = 60000) - public void increment() throws Throwable { - final int threads = 10; - final int items = 1000; - DB db = tx.makeTx(); - final long recid = db.getEngine().put(1L,Serializer.LONG); - db.commit(); - final List ex = new CopyOnWriteArrayList(); - final CountDownLatch l = new CountDownLatch(threads); - for(int i=0;i ex = new CopyOnWriteArrayList(); - final CountDownLatch l = new CountDownLatch(threads); - for(int i=0;i-1; i = i + 1 + i/1111){ //overflow is expected - out.pos = 0; - - DataIO.packInt(out, i); - in.pos = 0; - in.buf.clear(); - - int i2 = DataIO.unpackInt(in); - - Assert.assertEquals(i, i2); - - } - - } - - @Test public void testPackLong() throws Exception { - - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - DataIO.DataInputByteBuffer in = new DataIO.DataInputByteBuffer(ByteBuffer.wrap(out.buf,0, out.pos),0); - for(long i = 0;i>-1L ; i=i+1 + i/111){ //overflow is expected - out.pos = 0; - - DataIO.packLong(out, i); - in.pos = 0; - in.buf.clear(); - - long i2 = DataIO.unpackLong(in); - Assert.assertEquals(i, i2); - - } - } - - @Test public void testArrayPut(){ - assertEquals(asList(1,2,3,4,5), asList(BTreeMap.arrayPut(new Integer[]{1, 2, 4, 5}, 2, 3))); - assertEquals(asList(1,2,3,4,5), asList(BTreeMap.arrayPut(new Integer[]{2, 3, 4, 5}, 0, 1))); - assertEquals(asList(1,2,3,4,5), asList(BTreeMap.arrayPut(new Integer[]{1, 2, 3, 4}, 4, 5))); - } - - @Test - public void testNextPowTwo() throws Exception { - int val=9; - assertEquals(16, 1 << (32 - Integer.numberOfLeadingZeros(val - 1))); - val = 8; - assertEquals(8, 1 << (32 - Integer.numberOfLeadingZeros(val - 1))); - } - - - - /** clone value using serialization */ - public static E clone(E value, Serializer serializer){ - try{ - DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); - serializer.serialize(out,value); - DataIO.DataInputByteBuffer in = new DataIO.DataInputByteBuffer(ByteBuffer.wrap(out.copyBytes()), 0); - - return serializer.deserialize(in,out.pos); - }catch(IOException ee){ - throw new IOError(ee); - } - } - - - public static Serializer FAIL = new Serializer() { - @Override - public void serialize(DataOutput out, Object value) throws IOException { - throw new RuntimeException(); - } - - @Override - public Object deserialize(DataInput in, int available) throws IOException { - throw new RuntimeException(); - } - - @Override - public int fixedSize() { - return -1; - } - - }; - - - @Test public void testHexaConversion(){ - byte[] b = new byte[]{11,112,11,0,39,90}; - assertArrayEquals(b, DBMaker.fromHexa(DBMaker.toHexa(b))); - } - - /** - * Create temporary file in temp folder. All associated db files will be deleted on JVM exit. - */ - public static File tempDbFile() { - try{ - File index = File.createTempFile("mapdb","db"); - index.deleteOnExit(); - new File(index.getPath()+ StoreDirect.DATA_FILE_EXT).deleteOnExit(); - new File(index.getPath()+ StoreWAL.TRANS_LOG_FILE_EXT).deleteOnExit(); - - return index; - }catch(IOException e){ - throw new IOError(e); - } - } - - - public static String randomString(int size) { - String chars = "0123456789abcdefghijklmnopqrstuvwxyz !@#$%^&*()_+=-{}[]:\",./<>?|\\"; - StringBuilder b = new StringBuilder(size); - Random r = new Random(); - for(int i=0;iThis class is GWT compatible. + * *

The tests in this class for null keys and values only check maps for * which null keys and values are not allowed. There are currently no * {@link ConcurrentMap} implementations that support nulls. * * @author Jared Levy */ +@GwtCompatible public abstract class ConcurrentMapInterfaceTest extends MapInterfaceTest { protected ConcurrentMapInterfaceTest(boolean allowsNullKeys, boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, - boolean supportsClear, boolean supportsIteratorRemove, boolean supportsEntrySetValue) { + boolean supportsClear, boolean supportsIteratorRemove) { super(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove, - supportsClear,supportsIteratorRemove, supportsEntrySetValue); + supportsClear, supportsIteratorRemove); } /** @@ -65,7 +72,7 @@ protected abstract V getSecondValueNotInPopulatedMap() } } - public void testPutIfAbsentNewKey() { + @Test public void testPutIfAbsentNewKey() { final ConcurrentMap map; final K keyToPut; final V valueToPut; @@ -82,7 +89,6 @@ public void testPutIfAbsentNewKey() { assertEquals(valueToPut, map.get(keyToPut)); assertTrue(map.containsKey(keyToPut)); assertTrue(map.containsValue(valueToPut)); - assertEquals(initialSize + 1, map.size()); assertNull(oldValue); } else { @@ -96,7 +102,7 @@ public void testPutIfAbsentNewKey() { assertInvariants(map); } - public void testPutIfAbsentExistingKey() { + @Test public void testPutIfAbsentExistingKey() { final ConcurrentMap map; final K keyToPut; final V valueToPut; @@ -127,7 +133,7 @@ public void testPutIfAbsentExistingKey() { assertInvariants(map); } - public void testPutIfAbsentNullKey() { + @Test public void testPutIfAbsentNullKey() { if (allowsNullKeys) { return; // Not yet implemented } @@ -161,7 +167,7 @@ public void testPutIfAbsentNullKey() { assertInvariants(map); } - public void testPutIfAbsentNewKeyNullValue() { + @Test public void testPutIfAbsentNewKeyNullValue() { if (allowsNullValues) { return; // Not yet implemented } @@ -195,8 +201,40 @@ public void testPutIfAbsentNewKeyNullValue() { assertInvariants(map); } + @Test public void testPutIfAbsentExistingKeyNullValue() { + if (allowsNullValues) { + return; // Not yet implemented + } + final ConcurrentMap map; + final K keyToPut; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + keyToPut = map.keySet().iterator().next(); + int initialSize = map.size(); + if (supportsPut) { + try { + assertNull(map.putIfAbsent(keyToPut, null)); + } catch (NullPointerException e) { + // Optional. + } + } else { + try { + map.putIfAbsent(keyToPut, null); + fail("Expected UnsupportedOperationException or NullPointerException"); + } catch (UnsupportedOperationException e) { + // Expected. + } catch (NullPointerException e) { + // Expected. + } + } + assertEquals(initialSize, map.size()); + assertInvariants(map); + } - public void testRemoveKeyValueExisting() { + @Test public void testRemoveKeyValueExisting() { final ConcurrentMap map; final K keyToRemove; try { @@ -222,7 +260,7 @@ public void testRemoveKeyValueExisting() { assertInvariants(map); } - public void testRemoveKeyValueMissingKey() { + @Test public void testRemoveKeyValueMissingKey() { final ConcurrentMap map; final K keyToRemove; final V valueToRemove; @@ -248,7 +286,7 @@ public void testRemoveKeyValueMissingKey() { assertInvariants(map); } - public void testRemoveKeyValueDifferentValue() { + @Test public void testRemoveKeyValueDifferentValue() { final ConcurrentMap map; final K keyToRemove; final V valueToRemove; @@ -277,7 +315,7 @@ public void testRemoveKeyValueDifferentValue() { assertInvariants(map); } - public void testRemoveKeyValueNullKey() { + @Test public void testRemoveKeyValueNullKey() { if (allowsNullKeys) { return; // Not yet implemented } @@ -309,7 +347,7 @@ public void testRemoveKeyValueNullKey() { assertInvariants(map); } - public void testRemoveKeyValueExistingKeyNullValue() { + @Test public void testRemoveKeyValueExistingKeyNullValue() { if (allowsNullValues) { return; // Not yet implemented } @@ -341,7 +379,7 @@ public void testRemoveKeyValueExistingKeyNullValue() { assertInvariants(map); } - public void testRemoveKeyValueMissingKeyNullValue() { + @Test public void testRemoveKeyValueMissingKeyNullValue() { if (allowsNullValues) { return; // Not yet implemented } @@ -375,7 +413,7 @@ public void testRemoveKeyValueMissingKeyNullValue() { /* Replace2 tests call 2-parameter replace(key, value) */ - public void testReplace2ExistingKey() { + @Test public void testReplace2ExistingKey() { final ConcurrentMap map; final K keyToReplace; final V newValue; @@ -405,7 +443,7 @@ public void testReplace2ExistingKey() { assertInvariants(map); } - public void testReplace2MissingKey() { + @Test public void testReplace2MissingKey() { final ConcurrentMap map; final K keyToReplace; final V newValue; @@ -434,7 +472,7 @@ public void testReplace2MissingKey() { assertInvariants(map); } - public void testReplace2NullKey() { + @Test public void testReplace2NullKey() { if (allowsNullKeys) { return; // Not yet implemented } @@ -466,7 +504,7 @@ public void testReplace2NullKey() { assertInvariants(map); } - public void testReplace2ExistingKeyNullValue() { + @Test public void testReplace2ExistingKeyNullValue() { if (allowsNullValues) { return; // Not yet implemented } @@ -500,7 +538,7 @@ public void testReplace2ExistingKeyNullValue() { assertInvariants(map); } - public void testReplace2MissingKeyNullValue() { + @Test public void testReplace2MissingKeyNullValue() { if (allowsNullValues) { return; // Not yet implemented } @@ -536,7 +574,7 @@ public void testReplace2MissingKeyNullValue() { * Replace3 tests call 3-parameter replace(key, oldValue, newValue) */ - public void testReplace3ExistingKeyValue() { + @Test public void testReplace3ExistingKeyValue() { final ConcurrentMap map; final K keyToReplace; final V oldValue; @@ -568,7 +606,7 @@ public void testReplace3ExistingKeyValue() { assertInvariants(map); } - public void testReplace3ExistingKeyDifferentValue() { + @Test public void testReplace3ExistingKeyDifferentValue() { final ConcurrentMap map; final K keyToReplace; final V oldValue; @@ -601,7 +639,7 @@ public void testReplace3ExistingKeyDifferentValue() { assertInvariants(map); } - public void testReplace3MissingKey() { + @Test public void testReplace3MissingKey() { final ConcurrentMap map; final K keyToReplace; final V oldValue; @@ -632,7 +670,7 @@ public void testReplace3MissingKey() { assertInvariants(map); } - public void testReplace3NullKey() { + @Test public void testReplace3NullKey() { if (allowsNullKeys) { return; // Not yet implemented } @@ -666,7 +704,7 @@ public void testReplace3NullKey() { assertInvariants(map); } - public void testReplace3ExistingKeyNullOldValue() { + @Test public void testReplace3ExistingKeyNullOldValue() { if (allowsNullValues) { return; // Not yet implemented } @@ -702,7 +740,7 @@ public void testReplace3ExistingKeyNullOldValue() { assertInvariants(map); } - public void testReplace3MissingKeyNullOldValue() { + @Test public void testReplace3MissingKeyNullOldValue() { if (allowsNullValues) { return; // Not yet implemented } @@ -736,7 +774,7 @@ public void testReplace3MissingKeyNullOldValue() { assertInvariants(map); } - public void testReplace3MissingKeyNullNewValue() { + @Test public void testReplace3MissingKeyNullNewValue() { if (allowsNullValues) { return; // Not yet implemented } @@ -770,6 +808,7 @@ public void testReplace3MissingKeyNullNewValue() { assertInvariants(map); } + @Test public void testReplace3ExistingKeyValueNullNewValue() { if (allowsNullValues) { return; // Not yet implemented @@ -806,4 +845,4 @@ public void testReplace3ExistingKeyValueNullNewValue() { assertEquals(oldValue, map.get(keyToReplace)); assertInvariants(map); } -} +} \ No newline at end of file diff --git a/src/test/java/org/mapdb/guavaTests/GwtCompatible.java b/src/test/java/org/mapdb/guavaTests/GwtCompatible.java new file mode 100644 index 000000000..3fc80efd9 --- /dev/null +++ b/src/test/java/org/mapdb/guavaTests/GwtCompatible.java @@ -0,0 +1,4 @@ +package org.mapdb.guavaTests; + +public @interface GwtCompatible { +} diff --git a/src/test/java/org/mapdb/guavaTests/Helpers.java b/src/test/java/org/mapdb/guavaTests/Helpers.java new file mode 100644 index 000000000..e3bb89d89 --- /dev/null +++ b/src/test/java/org/mapdb/guavaTests/Helpers.java @@ -0,0 +1,18 @@ +package org.mapdb.guavaTests; + + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + + +public class Helpers { + public static Map.Entry mapEntry(final K key, final V value) { + Map m = new HashMap(); + m.put(key,value); + m = Collections.unmodifiableMap(m); + return m.entrySet().iterator().next(); + } +} + + diff --git a/src/test/java/org/mapdb/guavaTests/MapInterfaceTest.java b/src/test/java/org/mapdb/guavaTests/MapInterfaceTest.java new file mode 100644 index 000000000..4c55b39f5 --- /dev/null +++ b/src/test/java/org/mapdb/guavaTests/MapInterfaceTest.java @@ -0,0 +1,1676 @@ +/* + * Copyright (C) 2008 The Guava 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 + * + * http://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. + */ + +package org.mapdb.guavaTests; + +import static java.util.Collections.singleton; + +import static org.junit.Assert.*; +import org.junit.Test; +import org.mapdb.Verifiable; + + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/** + * Tests representing the contract of {@link Map}. Concrete subclasses of this + * base class test conformance of concrete {@link Map} subclasses to that + * contract. + * + * + * @param the type of keys used by the maps under test + * @param the type of mapped values used the maps under test + * + * @author George van den Driessche + */ +@GwtCompatible +public abstract class MapInterfaceTest { + + /** A key type that is not assignable to any classes but Object. */ + private static final class IncompatibleKeyType { + @Override public String toString() { + return "IncompatibleKeyType"; + } + } + + protected final boolean supportsPut; + protected final boolean supportsRemove; + protected final boolean supportsClear; + protected final boolean allowsNullKeys; + protected final boolean allowsNullValues; + protected final boolean supportsIteratorRemove; + + /** + * Creates a new, empty instance of the class under test. + * + * @return a new, empty map instance. + * @throws UnsupportedOperationException if it's not possible to make an + * empty instance of the class under test. + */ + protected abstract Map makeEmptyMap() + throws UnsupportedOperationException; + + /** + * Creates a new, non-empty instance of the class under test. + * + * @return a new, non-empty map instance. + * @throws UnsupportedOperationException if it's not possible to make a + * non-empty instance of the class under test. + */ + protected abstract Map makePopulatedMap() + throws UnsupportedOperationException; + + /** + * Creates a new key that is not expected to be found + * in {@link #makePopulatedMap()}. + * + * @return a key. + * @throws UnsupportedOperationException if it's not possible to make a key + * that will not be found in the map. + */ + protected abstract K getKeyNotInPopulatedMap() + throws UnsupportedOperationException; + + /** + * Creates a new value that is not expected to be found + * in {@link #makePopulatedMap()}. + * + * @return a value. + * @throws UnsupportedOperationException if it's not possible to make a value + * that will not be found in the map. + */ + protected abstract V getValueNotInPopulatedMap() + throws UnsupportedOperationException; + + /** + * Constructor that assigns {@code supportsIteratorRemove} the same value as + * {@code supportsRemove}. + */ + protected MapInterfaceTest( + boolean allowsNullKeys, + boolean allowsNullValues, + boolean supportsPut, + boolean supportsRemove, + boolean supportsClear) { + this(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove, + supportsClear, supportsRemove); + } + + /** + * Constructor with an explicit {@code supportsIteratorRemove} parameter. + */ + protected MapInterfaceTest( + boolean allowsNullKeys, + boolean allowsNullValues, + boolean supportsPut, + boolean supportsRemove, + boolean supportsClear, + boolean supportsIteratorRemove) { + this.supportsPut = supportsPut; + this.supportsRemove = supportsRemove; + this.supportsClear = supportsClear; + this.allowsNullKeys = allowsNullKeys; + this.allowsNullValues = allowsNullValues; + this.supportsIteratorRemove = supportsIteratorRemove; + } + + /** + * Used by tests that require a map, but don't care whether it's + * populated or not. + * + * @return a new map instance. + */ + protected Map makeEitherMap() { + try { + return makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return makeEmptyMap(); + } + } + + protected boolean supportsValuesHashCode(Map map) { + // get the first non-null value + Collection values = map.values(); + for (V value : values) { + if (value != null) { + try { + value.hashCode(); + } catch (Exception e) { + return false; + } + return true; + } + } + return true; + } + + /** + * Checks all the properties that should always hold of a map. Also calls + * {@link #assertMoreInvariants} to check invariants that are peculiar to + * specific implementations. + * + * @see #assertMoreInvariants + * @param map the map to check. + */ + protected final void assertInvariants(Map map) { + if(map instanceof Verifiable) + ((Verifiable)map).verify(); + + Set keySet = map.keySet(); + Collection valueCollection = map.values(); + Set> entrySet = map.entrySet(); + + assertEquals(map.size() == 0, map.isEmpty()); + assertEquals(map.size(), keySet.size()); + assertEquals(keySet.size() == 0, keySet.isEmpty()); + assertEquals(!keySet.isEmpty(), keySet.iterator().hasNext()); + + int expectedKeySetHash = 0; + for (K key : keySet) { + V value = map.get(key); + expectedKeySetHash += key != null ? key.hashCode() : 0; + assertTrue(map.containsKey(key)); + assertTrue(map.containsValue(value)); + assertTrue(valueCollection.contains(value)); + assertTrue(valueCollection.containsAll(Collections.singleton(value))); + assertTrue(entrySet.contains(mapEntry(key, value))); + assertTrue(allowsNullKeys || (key != null)); + } + +// assertEquals(expectedKeySetHash, keySet.hashCode()); + + assertEquals(map.size(), valueCollection.size()); + assertEquals(valueCollection.size() == 0, valueCollection.isEmpty()); + assertEquals( + !valueCollection.isEmpty(), valueCollection.iterator().hasNext()); + for (V value : valueCollection) { + assertTrue(map.containsValue(value)); + assertTrue(allowsNullValues || (value != null)); + } + + assertEquals(map.size(), entrySet.size()); + assertEquals(entrySet.size() == 0, entrySet.isEmpty()); + assertEquals(!entrySet.isEmpty(), entrySet.iterator().hasNext()); + assertFalse(entrySet.contains("foo")); + + boolean supportsValuesHashCode = supportsValuesHashCode(map); + if (supportsValuesHashCode) { + int expectedEntrySetHash = 0; + for (Entry entry : entrySet) { + assertTrue(map.containsKey(entry.getKey())); + assertTrue(map.containsValue(entry.getValue())); + int expectedHash = + (entry.getKey() == null ? 0 : entry.getKey().hashCode()) ^ + (entry.getValue() == null ? 0 : entry.getValue().hashCode()); + assertEquals(expectedHash, entry.hashCode()); + expectedEntrySetHash += expectedHash; + } + assertEquals(expectedEntrySetHash, entrySet.hashCode()); + assertTrue(entrySet.containsAll(new HashSet>(entrySet))); + assertTrue(entrySet.equals(new HashSet>(entrySet))); + } + + Object[] entrySetToArray1 = entrySet.toArray(); + assertEquals(map.size(), entrySetToArray1.length); + assertTrue(Arrays.asList(entrySetToArray1).containsAll(entrySet)); + + Entry[] entrySetToArray2 = new Entry[map.size() + 2]; + entrySetToArray2[map.size()] = mapEntry("foo", 1); + assertSame(entrySetToArray2, entrySet.toArray(entrySetToArray2)); + assertNull(entrySetToArray2[map.size()]); + assertTrue(Arrays.asList(entrySetToArray2).containsAll(entrySet)); + + Object[] valuesToArray1 = valueCollection.toArray(); + assertEquals(map.size(), valuesToArray1.length); + assertTrue(Arrays.asList(valuesToArray1).containsAll(valueCollection)); + + Object[] valuesToArray2 = new Object[map.size() + 2]; + valuesToArray2[map.size()] = "foo"; + assertSame(valuesToArray2, valueCollection.toArray(valuesToArray2)); + assertNull(valuesToArray2[map.size()]); + assertTrue(Arrays.asList(valuesToArray2).containsAll(valueCollection)); + + if (supportsValuesHashCode) { + int expectedHash = 0; + for (Entry entry : entrySet) { + expectedHash += entry.hashCode(); + } + assertEquals(expectedHash, map.hashCode()); + } + + assertMoreInvariants(map); + } + + /** + * Override this to check invariants which should hold true for a particular + * implementation, but which are not generally applicable to every instance + * of Map. + * + * @param map the map whose additional invariants to check. + */ + protected void assertMoreInvariants(Map map) { + } + + @Test public void testClear() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + if (supportsClear) { + map.clear(); + assertTrue(map.isEmpty()); + } else { + try { + map.clear(); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testContainsKey() { + final Map map; + final K unmappedKey; + try { + map = makePopulatedMap(); + unmappedKey = getKeyNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertFalse(map.containsKey(unmappedKey)); + try { + assertFalse(map.containsKey(new IncompatibleKeyType())); + } catch (ClassCastException tolerated) {} + assertTrue(map.containsKey(map.keySet().iterator().next())); + if (allowsNullKeys) { + map.containsKey(null); + } else { + try { + map.containsKey(null); + } catch (NullPointerException optional) { + } + } + assertInvariants(map); + } + + @Test public void testContainsValue() { + final Map map; + final V unmappedValue; + try { + map = makePopulatedMap(); + unmappedValue = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertFalse(map.containsValue(unmappedValue)); + assertTrue(map.containsValue(map.values().iterator().next())); + if (allowsNullValues) { + map.containsValue(null); + } else { + try { + map.containsKey(null); + } catch (NullPointerException optional) { + } + } + assertInvariants(map); + } + + @Test public void testEntrySet() { + final Map map; + final Set> entrySet; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertInvariants(map); + + entrySet = map.entrySet(); + final K unmappedKey; + final V unmappedValue; + try { + unmappedKey = getKeyNotInPopulatedMap(); + unmappedValue = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + for (Entry entry : entrySet) { + assertFalse(unmappedKey.equals(entry.getKey())); + assertFalse(unmappedValue.equals(entry.getValue())); + } + } + + @Test public void testEntrySetForEmptyMap() { + final Map map; + try { + map = makeEmptyMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertInvariants(map); + } + + @Test public void testEntrySetContainsEntryIncompatibleKey() { + final Map map; + final Set> entrySet; + try { + map = makeEitherMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertInvariants(map); + + entrySet = map.entrySet(); + final V unmappedValue; + try { + unmappedValue = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + Entry entry + = mapEntry(new IncompatibleKeyType(), unmappedValue); + try { + assertFalse(entrySet.contains(entry)); + } catch (ClassCastException tolerated) {} + } + + @Test public void testEntrySetContainsEntryNullKeyPresent() { + if (!allowsNullKeys || !supportsPut) { + return; + } + final Map map; + final Set> entrySet; + try { + map = makeEitherMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertInvariants(map); + + entrySet = map.entrySet(); + final V unmappedValue; + try { + unmappedValue = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + map.put(null, unmappedValue); + Entry entry = mapEntry(null, unmappedValue); + assertTrue(entrySet.contains(entry)); + assertFalse(entrySet.contains(mapEntry(null, null))); + } + + @Test public void testEntrySetContainsEntryNullKeyMissing() { + final Map map; + final Set> entrySet; + try { + map = makeEitherMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertInvariants(map); + + entrySet = map.entrySet(); + final V unmappedValue; + try { + unmappedValue = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + Entry entry = mapEntry(null, unmappedValue); + try { + assertFalse(entrySet.contains(entry)); + } catch (NullPointerException e) { + assertFalse(allowsNullKeys); + } + try { + assertFalse(entrySet.contains(mapEntry(null, null))); + } catch (NullPointerException e) { + assertFalse(allowsNullKeys && allowsNullValues); + } + } + + @Test public void testEntrySetIteratorRemove() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + Iterator> iterator = entrySet.iterator(); + if (supportsIteratorRemove) { + int initialSize = map.size(); + Entry entry = iterator.next(); + Entry entryCopy = Helpers.mapEntry( + entry.getKey(), entry.getValue()); + + iterator.remove(); + assertEquals(initialSize - 1, map.size()); + + // Use "entryCopy" instead of "entry" because "entry" might be invalidated after + // iterator.remove(). + assertFalse(entrySet.contains(entryCopy)); + assertInvariants(map); + try { + iterator.remove(); + fail("Expected IllegalStateException."); + } catch (IllegalStateException e) { + // Expected. + } + } else { + try { + iterator.next(); + iterator.remove(); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testEntrySetRemove() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + if (supportsRemove) { + int initialSize = map.size(); + boolean didRemove = entrySet.remove(entrySet.iterator().next()); + assertTrue(didRemove); + assertEquals(initialSize - 1, map.size()); + } else { + try { + entrySet.remove(entrySet.iterator().next()); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testEntrySetRemoveMissingKey() { + final Map map; + final K key; + try { + map = makeEitherMap(); + key = getKeyNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + Entry entry + = mapEntry(key, getValueNotInPopulatedMap()); + int initialSize = map.size(); + if (supportsRemove) { + boolean didRemove = entrySet.remove(entry); + assertFalse(didRemove); + } else { + try { + boolean didRemove = entrySet.remove(entry); + assertFalse(didRemove); + } catch (UnsupportedOperationException optional) {} + } + assertEquals(initialSize, map.size()); + assertFalse(map.containsKey(key)); + assertInvariants(map); + } + + @Test public void testEntrySetRemoveDifferentValue() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + K key = map.keySet().iterator().next(); + Entry entry + = mapEntry(key, getValueNotInPopulatedMap()); + int initialSize = map.size(); + if (supportsRemove) { + boolean didRemove = entrySet.remove(entry); + assertFalse(didRemove); + } else { + try { + boolean didRemove = entrySet.remove(entry); + assertFalse(didRemove); + } catch (UnsupportedOperationException optional) {} + } + assertEquals(initialSize, map.size()); + assertTrue(map.containsKey(key)); + assertInvariants(map); + } + + @Test public void testEntrySetRemoveNullKeyPresent() { + if (!allowsNullKeys || !supportsPut || !supportsRemove) { + return; + } + final Map map; + final Set> entrySet; + try { + map = makeEitherMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertInvariants(map); + + entrySet = map.entrySet(); + final V unmappedValue; + try { + unmappedValue = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + map.put(null, unmappedValue); + assertEquals(unmappedValue, map.get(null)); + assertTrue(map.containsKey(null)); + Entry entry = mapEntry(null, unmappedValue); + assertTrue(entrySet.remove(entry)); + assertNull(map.get(null)); + assertFalse(map.containsKey(null)); + } + + @Test public void testEntrySetRemoveNullKeyMissing() { + final Map map; + try { + map = makeEitherMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + Entry entry + = mapEntry(null, getValueNotInPopulatedMap()); + int initialSize = map.size(); + if (supportsRemove) { + try { + boolean didRemove = entrySet.remove(entry); + assertFalse(didRemove); + } catch (NullPointerException e) { + assertFalse(allowsNullKeys); + } + } else { + try { + boolean didRemove = entrySet.remove(entry); + assertFalse(didRemove); + } catch (UnsupportedOperationException optional) {} + } + assertEquals(initialSize, map.size()); + assertInvariants(map); + } + + @Test public void testEntrySetRemoveAll() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + + Entry entryToRemove = entrySet.iterator().next(); + Set> entriesToRemove = singleton(entryToRemove); + if (supportsRemove) { + // We use a copy of "entryToRemove" in the assertion because "entryToRemove" might be + // invalidated and have undefined behavior after entrySet.removeAll(entriesToRemove), + // for example entryToRemove.getValue() might be null. + Entry entryToRemoveCopy = Helpers.mapEntry( + entryToRemove.getKey(), entryToRemove.getValue()); + + int initialSize = map.size(); + boolean didRemove = entrySet.removeAll(entriesToRemove); + assertTrue(didRemove); + assertEquals(initialSize - entriesToRemove.size(), map.size()); + + // Use "entryToRemoveCopy" instead of "entryToRemove" because it might be invalidated and + // have undefined behavior after entrySet.removeAll(entriesToRemove), + assertFalse(entrySet.contains(entryToRemoveCopy)); + } else { + try { + entrySet.removeAll(entriesToRemove); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testEntrySetRemoveAllNullFromEmpty() { + final Map map; + try { + map = makeEmptyMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + if (supportsRemove) { + try { + entrySet.removeAll(null); + fail("Expected NullPointerException."); + } catch (NullPointerException e) { + // Expected. + } + } else { + try { + entrySet.removeAll(null); + fail("Expected UnsupportedOperationException or NullPointerException."); + } catch (UnsupportedOperationException e) { + // Expected. + } catch (NullPointerException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testEntrySetRetainAll() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + Set> entriesToRetain = + singleton(entrySet.iterator().next()); + if (supportsRemove) { + boolean shouldRemove = (entrySet.size() > entriesToRetain.size()); + boolean didRemove = entrySet.retainAll(entriesToRetain); + assertEquals(shouldRemove, didRemove); + assertEquals(entriesToRetain.size(), map.size()); + for (Entry entry : entriesToRetain) { + assertTrue(entrySet.contains(entry)); + } + } else { + try { + entrySet.retainAll(entriesToRetain); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testEntrySetRetainAllNullFromEmpty() { + final Map map; + try { + map = makeEmptyMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + if (supportsRemove) { + try { + entrySet.retainAll(null); + // Returning successfully is not ideal, but tolerated. + } catch (NullPointerException e) { + // Expected. + } + } else { + try { + entrySet.retainAll(null); + // We have to tolerate a successful return (Sun bug 4802647) + } catch (UnsupportedOperationException e) { + // Expected. + } catch (NullPointerException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testEntrySetClear() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + if (supportsClear) { + entrySet.clear(); + assertTrue(entrySet.isEmpty()); + } else { + try { + entrySet.clear(); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testEntrySetAddAndAddAll() { + final Map map = makeEitherMap(); + + Set> entrySet = map.entrySet(); + final Entry entryToAdd = mapEntry(null, null); + try { + entrySet.add(entryToAdd); + fail("Expected UnsupportedOperationException or NullPointerException."); + } catch (UnsupportedOperationException e) { + // Expected. + } catch (NullPointerException e) { + // Expected. + } + assertInvariants(map); + + try { + entrySet.addAll(singleton(entryToAdd)); + fail("Expected UnsupportedOperationException or NullPointerException."); + } catch (UnsupportedOperationException e) { + // Expected. + } catch (NullPointerException e) { + // Expected. + } + assertInvariants(map); + } + + @Test public void testEntrySetSetValue() { + // put() also support Entry.setValue(). + if (!supportsPut) { + return; + } + + final Map map; + final V valueToSet; + try { + map = makePopulatedMap(); + valueToSet = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + Entry entry = entrySet.iterator().next(); + final V oldValue = entry.getValue(); + final V returnedValue = entry.setValue(valueToSet); + assertEquals(oldValue, returnedValue); + assertTrue(entrySet.contains( + mapEntry(entry.getKey(), valueToSet))); + assertEquals(valueToSet, map.get(entry.getKey())); + assertInvariants(map); + } + + @Test public void testEntrySetSetValueSameValue() { + // put() also support Entry.setValue(). + if (!supportsPut) { + return; + } + + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set> entrySet = map.entrySet(); + Entry entry = entrySet.iterator().next(); + final V oldValue = entry.getValue(); + final V returnedValue = entry.setValue(oldValue); + assertEquals(oldValue, returnedValue); + assertTrue(entrySet.contains( + mapEntry(entry.getKey(), oldValue))); + assertEquals(oldValue, map.get(entry.getKey())); + assertInvariants(map); + } + + @Test public void testEqualsForEqualMap() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + assertEquals(map, map); + assertEquals(makePopulatedMap(), map); + assertFalse(map.equals(Collections.emptyMap())); + //no-inspection ObjectEqualsNull + assertFalse(map.equals(null)); + } + + @Test public void testEqualsForLargerMap() { + if (!supportsPut) { + return; + } + + final Map map; + final Map largerMap; + try { + map = makePopulatedMap(); + largerMap = makePopulatedMap(); + largerMap.put(getKeyNotInPopulatedMap(), getValueNotInPopulatedMap()); + } catch (UnsupportedOperationException e) { + return; + } + + assertFalse(map.equals(largerMap)); + } + + @Test public void testEqualsForSmallerMap() { + if (!supportsRemove) { + return; + } + + final Map map; + final Map smallerMap; + try { + map = makePopulatedMap(); + smallerMap = makePopulatedMap(); + smallerMap.remove(smallerMap.keySet().iterator().next()); + } catch (UnsupportedOperationException e) { + return; + } + + assertFalse(map.equals(smallerMap)); + } + + @Test public void testEqualsForEmptyMap() { + final Map map; + try { + map = makeEmptyMap(); + } catch (UnsupportedOperationException e) { + return; + } + + assertEquals(map, map); + assertEquals(makeEmptyMap(), map); + assertEquals(Collections.emptyMap(), map); + assertFalse(map.equals(Collections.emptySet())); + //noinspection ObjectEqualsNull + assertFalse(map.equals(null)); + } + + @Test public void testGet() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + for (Entry entry : map.entrySet()) { + assertEquals(entry.getValue(), map.get(entry.getKey())); + } + + K unmappedKey = null; + try { + unmappedKey = getKeyNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertNull(map.get(unmappedKey)); + } + + @Test public void testGetForEmptyMap() { + final Map map; + K unmappedKey = null; + try { + map = makeEmptyMap(); + unmappedKey = getKeyNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertNull(map.get(unmappedKey)); + } + + @Test public void testGetNull() { + Map map = makeEitherMap(); + if (allowsNullKeys) { + if (allowsNullValues) { + + } else { + assertEquals(map.containsKey(null), map.get(null) != null); + } + } else { + try { + map.get(null); + } catch (NullPointerException optional) { + } + } + assertInvariants(map); + } + + @Test public void testHashCode() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertInvariants(map); + } + + @Test public void testHashCodeForEmptyMap() { + final Map map; + try { + map = makeEmptyMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertInvariants(map); + } + + @Test public void testPutNewKey() { + final Map map = makeEitherMap(); + final K keyToPut; + final V valueToPut; + try { + keyToPut = getKeyNotInPopulatedMap(); + valueToPut = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + if (supportsPut) { + int initialSize = map.size(); + V oldValue = map.put(keyToPut, valueToPut); + assertEquals(valueToPut, map.get(keyToPut)); + assertTrue(map.containsKey(keyToPut)); + assertTrue(map.containsValue(valueToPut)); + assertEquals(initialSize + 1, map.size()); + assertNull(oldValue); + } else { + try { + map.put(keyToPut, valueToPut); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testPutExistingKey() { + final Map map; + final K keyToPut; + final V valueToPut; + try { + map = makePopulatedMap(); + valueToPut = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + keyToPut = map.keySet().iterator().next(); + if (supportsPut) { + int initialSize = map.size(); + map.put(keyToPut, valueToPut); + assertEquals(valueToPut, map.get(keyToPut)); + assertTrue(map.containsKey(keyToPut)); + assertTrue(map.containsValue(valueToPut)); + assertEquals(initialSize, map.size()); + } else { + try { + map.put(keyToPut, valueToPut); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testPutNullKey() { + if (!supportsPut) { + return; + } + final Map map = makeEitherMap(); + final V valueToPut; + try { + valueToPut = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + if (allowsNullKeys) { + final V oldValue = map.get(null); + final V returnedValue = map.put(null, valueToPut); + assertEquals(oldValue, returnedValue); + assertEquals(valueToPut, map.get(null)); + assertTrue(map.containsKey(null)); + assertTrue(map.containsValue(valueToPut)); + } else { + try { + map.put(null, valueToPut); + fail("Expected RuntimeException"); + } catch (RuntimeException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testPutNullValue() { + if (!supportsPut) { + return; + } + final Map map = makeEitherMap(); + final K keyToPut; + try { + keyToPut = getKeyNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + if (allowsNullValues) { + int initialSize = map.size(); + final V oldValue = map.get(keyToPut); + final V returnedValue = map.put(keyToPut, null); + assertEquals(oldValue, returnedValue); + assertNull(map.get(keyToPut)); + assertTrue(map.containsKey(keyToPut)); + assertTrue(map.containsValue(null)); + assertEquals(initialSize + 1, map.size()); + } else { + try { + map.put(keyToPut, null); + fail("Expected RuntimeException"); + } catch (RuntimeException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testPutNullValueForExistingKey() { + if (!supportsPut) { + return; + } + final Map map; + final K keyToPut; + try { + map = makePopulatedMap(); + keyToPut = map.keySet().iterator().next(); + } catch (UnsupportedOperationException e) { + return; + } + if (allowsNullValues) { + int initialSize = map.size(); + final V oldValue = map.get(keyToPut); + final V returnedValue = map.put(keyToPut, null); + assertEquals(oldValue, returnedValue); + assertNull(map.get(keyToPut)); + assertTrue(map.containsKey(keyToPut)); + assertTrue(map.containsValue(null)); + assertEquals(initialSize, map.size()); + } else { + try { + map.put(keyToPut, null); + fail("Expected RuntimeException"); + } catch (RuntimeException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testPutAllNewKey() { + final Map map = makeEitherMap(); + final K keyToPut; + final V valueToPut; + try { + keyToPut = getKeyNotInPopulatedMap(); + valueToPut = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + final Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); + if (supportsPut) { + int initialSize = map.size(); + map.putAll(mapToPut); + assertEquals(valueToPut, map.get(keyToPut)); + assertTrue(map.containsKey(keyToPut)); + assertTrue(map.containsValue(valueToPut)); + assertEquals(initialSize + 1, map.size()); + } else { + try { + map.putAll(mapToPut); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testPutAllExistingKey() { + final Map map; + final K keyToPut; + final V valueToPut; + try { + map = makePopulatedMap(); + valueToPut = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + keyToPut = map.keySet().iterator().next(); + final Map mapToPut = Collections.singletonMap(keyToPut, valueToPut); + int initialSize = map.size(); + if (supportsPut) { + map.putAll(mapToPut); + assertEquals(valueToPut, map.get(keyToPut)); + assertTrue(map.containsKey(keyToPut)); + assertTrue(map.containsValue(valueToPut)); + } else { + try { + map.putAll(mapToPut); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertEquals(initialSize, map.size()); + assertInvariants(map); + } + + @Test public void testRemove() { + final Map map; + final K keyToRemove; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + keyToRemove = map.keySet().iterator().next(); + if (supportsRemove) { + int initialSize = map.size(); + V expectedValue = map.get(keyToRemove); + V oldValue = map.remove(keyToRemove); + assertEquals(expectedValue, oldValue); + assertFalse(map.containsKey(keyToRemove)); + assertEquals(initialSize - 1, map.size()); + } else { + try { + map.remove(keyToRemove); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testRemoveMissingKey() { + final Map map; + final K keyToRemove; + try { + map = makePopulatedMap(); + keyToRemove = getKeyNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + if (supportsRemove) { + int initialSize = map.size(); + assertNull(map.remove(keyToRemove)); + assertEquals(initialSize, map.size()); + } else { + try { + map.remove(keyToRemove); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testSize() { + assertInvariants(makeEitherMap()); + } + + @Test public void testKeySetRemove() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set keys = map.keySet(); + K key = keys.iterator().next(); + if (supportsRemove) { + int initialSize = map.size(); + keys.remove(key); + assertEquals(initialSize - 1, map.size()); + assertFalse(map.containsKey(key)); + } else { + try { + keys.remove(key); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testKeySetRemoveAll() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set keys = map.keySet(); + K key = keys.iterator().next(); + if (supportsRemove) { + int initialSize = map.size(); + assertTrue(keys.removeAll(Collections.singleton(key))); + assertEquals(initialSize - 1, map.size()); + assertFalse(map.containsKey(key)); + } else { + try { + keys.removeAll(Collections.singleton(key)); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testKeySetRetainAll() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set keys = map.keySet(); + K key = keys.iterator().next(); + if (supportsRemove) { + keys.retainAll(Collections.singleton(key)); + assertEquals(1, map.size()); + assertTrue(map.containsKey(key)); + } else { + try { + keys.retainAll(Collections.singleton(key)); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testKeySetClear() { + final Map map; + try { + map = makeEitherMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set keySet = map.keySet(); + if (supportsClear) { + keySet.clear(); + assertTrue(keySet.isEmpty()); + } else { + try { + keySet.clear(); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testKeySetRemoveAllNullFromEmpty() { + final Map map; + try { + map = makeEmptyMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set keySet = map.keySet(); + if (supportsRemove) { + try { + keySet.removeAll(null); + fail("Expected NullPointerException."); + } catch (NullPointerException e) { + // Expected. + } + } else { + try { + keySet.removeAll(null); + fail("Expected UnsupportedOperationException or NullPointerException."); + } catch (UnsupportedOperationException e) { + // Expected. + } catch (NullPointerException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testKeySetRetainAllNullFromEmpty() { + final Map map; + try { + map = makeEmptyMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Set keySet = map.keySet(); + if (supportsRemove) { + try { + keySet.retainAll(null); + // Returning successfully is not ideal, but tolerated. + } catch (NullPointerException e) { + // Expected. + } + } else { + try { + keySet.retainAll(null); + // We have to tolerate a successful return (Sun bug 4802647) + } catch (UnsupportedOperationException e) { + // Expected. + } catch (NullPointerException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testValues() { + final Map map; + final Collection valueCollection; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + assertInvariants(map); + + valueCollection = map.values(); + final V unmappedValue; + try { + unmappedValue = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + for (V value : valueCollection) { + assertFalse(unmappedValue.equals(value)); + } + } + + @Test public void testValuesIteratorRemove() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Collection valueCollection = map.values(); + Iterator iterator = valueCollection.iterator(); + if (supportsIteratorRemove) { + int initialSize = map.size(); + iterator.next(); + iterator.remove(); + assertEquals(initialSize - 1, map.size()); + // (We can't assert that the values collection no longer contains the + // removed value, because the underlying map can have multiple mappings + // to the same value.) + assertInvariants(map); + try { + iterator.remove(); + fail("Expected IllegalStateException."); + } catch (IllegalStateException e) { + // Expected. + } + } else { + try { + iterator.next(); + iterator.remove(); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testValuesRemove() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Collection valueCollection = map.values(); + if (supportsRemove) { + int initialSize = map.size(); + valueCollection.remove(valueCollection.iterator().next()); + assertEquals(initialSize - 1, map.size()); + // (We can't assert that the values collection no longer contains the + // removed value, because the underlying map can have multiple mappings + // to the same value.) + } else { + try { + valueCollection.remove(valueCollection.iterator().next()); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testValuesRemoveMissing() { + final Map map; + final V valueToRemove; + try { + map = makeEitherMap(); + valueToRemove = getValueNotInPopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Collection valueCollection = map.values(); + int initialSize = map.size(); + if (supportsRemove) { + assertFalse(valueCollection.remove(valueToRemove)); + } else { + try { + assertFalse(valueCollection.remove(valueToRemove)); + } catch (UnsupportedOperationException e) { + // Tolerated. + } + } + assertEquals(initialSize, map.size()); + assertInvariants(map); + } + + @Test public void testValuesRemoveAll() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Collection valueCollection = map.values(); + Set valuesToRemove = singleton(valueCollection.iterator().next()); + if (supportsRemove) { + valueCollection.removeAll(valuesToRemove); + for (V value : valuesToRemove) { + assertFalse(valueCollection.contains(value)); + } + for (V value : valueCollection) { + assertFalse(valuesToRemove.contains(value)); + } + } else { + try { + valueCollection.removeAll(valuesToRemove); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testValuesRemoveAllNullFromEmpty() { + final Map map; + try { + map = makeEmptyMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Collection values = map.values(); + if (supportsRemove) { + try { + values.removeAll(null); + // Returning successfully is not ideal, but tolerated. + } catch (NullPointerException e) { + // Expected. + } + } else { + try { + values.removeAll(null); + // We have to tolerate a successful return (Sun bug 4802647) + } catch (UnsupportedOperationException e) { + // Expected. + } catch (NullPointerException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testValuesRetainAll() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Collection valueCollection = map.values(); + Set valuesToRetain = singleton(valueCollection.iterator().next()); + if (supportsRemove) { + valueCollection.retainAll(valuesToRetain); + for (V value : valuesToRetain) { + assertTrue(valueCollection.contains(value)); + } + for (V value : valueCollection) { + assertTrue(valuesToRetain.contains(value)); + } + } else { + try { + valueCollection.retainAll(valuesToRetain); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testValuesRetainAllNullFromEmpty() { + final Map map; + try { + map = makeEmptyMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Collection values = map.values(); + if (supportsRemove) { + try { + values.retainAll(null); + // Returning successfully is not ideal, but tolerated. + } catch (NullPointerException e) { + // Expected. + } + } else { + try { + values.retainAll(null); + // We have to tolerate a successful return (Sun bug 4802647) + } catch (UnsupportedOperationException e) { + // Expected. + } catch (NullPointerException e) { + // Expected. + } + } + assertInvariants(map); + } + + @Test public void testValuesClear() { + final Map map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + + Collection valueCollection = map.values(); + if (supportsClear) { + valueCollection.clear(); + assertTrue(valueCollection.isEmpty()); + } else { + try { + valueCollection.clear(); + fail("Expected UnsupportedOperationException."); + } catch (UnsupportedOperationException e) { + // Expected. + } + } + assertInvariants(map); + } + + static Entry mapEntry(K key, V value) { + return Collections.singletonMap(key, value).entrySet().iterator().next(); + } +} diff --git a/src/test/java/org/mapdb/guavaTests/SortedMapInterfaceTest.java b/src/test/java/org/mapdb/guavaTests/SortedMapInterfaceTest.java new file mode 100644 index 000000000..b631c17b9 --- /dev/null +++ b/src/test/java/org/mapdb/guavaTests/SortedMapInterfaceTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2009 The Guava 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 + * + * http://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. + */ + +package org.mapdb.guavaTests; + + +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.SortedMap; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Tests representing the contract of {@link SortedMap}. Concrete subclasses of + * this base class test conformance of concrete {@link SortedMap} subclasses to + * that contract. + * + * @author Jared Levy + */ +@GwtCompatible +public abstract class SortedMapInterfaceTest + extends MapInterfaceTest { + + protected SortedMapInterfaceTest(boolean allowsNullKeys, + boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, + boolean supportsClear) { + super(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove, + supportsClear); + } + + @Override protected abstract SortedMap makeEmptyMap() + throws UnsupportedOperationException; + + @Override protected abstract SortedMap makePopulatedMap() + throws UnsupportedOperationException; + + @Override protected SortedMap makeEitherMap() { + try { + return makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return makeEmptyMap(); + } + } + + @Test public void testTailMapWriteThrough() { + final SortedMap map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + if (map.size() < 2 || !supportsPut) { + return; + } + Iterator> iterator = map.entrySet().iterator(); + Entry firstEntry = iterator.next(); + Entry secondEntry = iterator.next(); + K key = secondEntry.getKey(); + SortedMap subMap = map.tailMap(key); + V value = getValueNotInPopulatedMap(); + subMap.put(key, value); +// assertEquals(secondEntry.getValue(), value); + assertEquals(map.get(key), value); + try { + subMap.put(firstEntry.getKey(), value); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + @Test public void testTailMapRemoveThrough() { + final SortedMap map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + int oldSize = map.size(); + if (map.size() < 2 || !supportsRemove) { + return; + } + Iterator> iterator = map.entrySet().iterator(); + Entry firstEntry = iterator.next(); + Entry secondEntry = iterator.next(); + K key = secondEntry.getKey(); + SortedMap subMap = map.tailMap(key); + subMap.remove(key); + assertNull(subMap.remove(firstEntry.getKey())); + assertEquals(map.size(), oldSize - 1); + assertFalse(map.containsKey(key)); + assertEquals(subMap.size(), oldSize - 2); + } + + @Test public void testTailMapClearThrough() { + final SortedMap map; + try { + map = makePopulatedMap(); + } catch (UnsupportedOperationException e) { + return; + } + int oldSize = map.size(); + if (map.size() < 2 || !supportsClear) { + return; + } + Iterator> iterator = map.entrySet().iterator(); + iterator.next(); // advance + Entry secondEntry = iterator.next(); + K key = secondEntry.getKey(); + SortedMap subMap = map.tailMap(key); + int subMapSize = subMap.size(); + subMap.clear(); + assertEquals(map.size(), oldSize - subMapSize); + assertTrue(subMap.isEmpty()); + } +} diff --git a/src/test/java/org/mapdb/io/DataIOTest.java b/src/test/java/org/mapdb/io/DataIOTest.java new file mode 100644 index 000000000..ed532fcd8 --- /dev/null +++ b/src/test/java/org/mapdb/io/DataIOTest.java @@ -0,0 +1,338 @@ +package org.mapdb.io; + +import org.junit.Test; +import org.mapdb.DBException; + + +import java.io.*; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Random; + +import static org.junit.Assert.*; +import static org.mapdb.io.DataIO.*; + +public class DataIOTest { + + @Test public void parity1() { + assertEquals(Long.parseLong("1", 2), parity1Set(0)); + assertEquals(Long.parseLong("10", 2), parity1Set(2)); + assertEquals(Long.parseLong("111", 2), parity1Set(Long.parseLong("110", 2))); + assertEquals(Long.parseLong("1110", 2), parity1Set(Long.parseLong("1110", 2))); + assertEquals(Long.parseLong("1011", 2), parity1Set(Long.parseLong("1010", 2))); + assertEquals(Long.parseLong("11111", 2), parity1Set(Long.parseLong("11110", 2))); + + assertEquals(0, parity1Get(Long.parseLong("1", 2))); + try { + parity1Get(Long.parseLong("0", 2)); + fail(); + }catch(DBException.PointerChecksumBroken e){ + //TODO check mapdb specific error; + } + try { + parity1Get(Long.parseLong("110", 2)); + fail(); + }catch(DBException.PointerChecksumBroken e){ + //TODO check mapdb specific error; + } + } + + + @Test public void parityBasic(){ + for(long i=0;i>>48==0;i=i+1+i/10000){ + DataIO.putSixLong(b,2,i); + assertEquals(i, DataIO.getSixLong(b,2)); + } + } + + @Test public void testNextPowTwo(){ + assertEquals(1, DataIO.nextPowTwo(1)); + assertEquals(2, DataIO.nextPowTwo(2)); + assertEquals(4, DataIO.nextPowTwo(3)); + assertEquals(4, DataIO.nextPowTwo(4)); + + assertEquals(64, DataIO.nextPowTwo(33)); + assertEquals(64, DataIO.nextPowTwo(61)); + + assertEquals(1024, DataIO.nextPowTwo(777)); + assertEquals(1024, DataIO.nextPowTwo(1024)); + + assertEquals(1073741824, DataIO.nextPowTwo(1073741824-100)); + assertEquals(1073741824, DataIO.nextPowTwo((int) (1073741824*0.7))); + assertEquals(1073741824, DataIO.nextPowTwo(1073741824)); + } + + + @Test public void testNextPowTwoLong(){ + assertEquals(1, DataIO.nextPowTwo(1L)); + assertEquals(2, DataIO.nextPowTwo(2L)); + assertEquals(4, DataIO.nextPowTwo(3L)); + assertEquals(4, DataIO.nextPowTwo(4L)); + + assertEquals(64, DataIO.nextPowTwo(33L)); + assertEquals(64, DataIO.nextPowTwo(61L)); + + assertEquals(1024, DataIO.nextPowTwo(777L)); + assertEquals(1024, DataIO.nextPowTwo(1024L)); + + assertEquals(1073741824, DataIO.nextPowTwo(1073741824L-100)); + assertEquals(1073741824, DataIO.nextPowTwo((long) (1073741824*0.7))); + assertEquals(1073741824, DataIO.nextPowTwo(1073741824L)); + } + + @Test public void testNextPowTwo2(){ + for(int i=1;i<1073750016;i+= 1 + i/100000){ + int pow = nextPowTwo(i); + assertTrue(pow>=i); + assertTrue(pow/2=i); + assertTrue(pow/20; i = i + 1 + i / 10000) { + in.pos = 10; + out.pos = 10; + + DataIO.packLong((DataOutput)out,i); + long i2 = DataIO.unpackLong(in); + + assertEquals(i,i2); + assertEquals(in.pos,out.pos); + } + + } + + @Test public void packInt() throws IOException { + DataInput2.ByteArray in = new DataInput2.ByteArray(new byte[20]); + DataOutput2 out = new DataOutput2(); + out.buf = in.buf; + for (int i = 0; i >0; i = i + 1 + i / 10000) { + in.pos = 10; + out.pos = 10; + + DataIO.packInt((DataOutput)out,i); + long i2 = DataIO.unpackInt(in); + + assertEquals(i,i2); + assertEquals(in.pos,out.pos); + } + + } + + + + @Test + public void packedLong_volume() throws IOException { + if(TT.shortTest()) + return; + + DataOutput2 out = new DataOutput2(); + DataInput2.ByteArray in = new DataInput2.ByteArray(out.buf); + Volume v = new SingleByteArrayVol(out.buf); + + for (long i = 0; i < 1e6; i++) { + Arrays.fill(out.buf, (byte) 0); + out.pos=10; + out.packLong(i); + assertEquals(i, v.getPackedLong(10)& DataIO.PACK_LONG_RESULT_MASK); + assertEquals(DataIO.packLongSize(i), v.getPackedLong(10)>>>60); + + Arrays.fill(out.buf, (byte) 0); + out.pos=10; + out.packInt((int)i); + assertEquals(i, v.getPackedLong(10)& DataIO.PACK_LONG_RESULT_MASK); + assertEquals(DataIO.packLongSize(i), v.getPackedLong(10)>>>60); + + Arrays.fill(out.buf, (byte) 0); + v.putPackedLong(10, i); + in.pos=10; + assertEquals(i, in.unpackLong()); + in.pos=10; + assertEquals(i, in.unpackInt()); + } + } + +*/ + @Test public void testHexaConversion(){ + byte[] b = new byte[]{11,112,11,0,39,90}; + assertTrue(Arrays.equals(b, DataIO.fromHexa(DataIO.toHexa(b)))); + } + @Test public void int2Long(){ + assertEquals(0x7fffffffL, DataIO.intToLong(0x7fffffff)); + assertEquals(0x80000000L, DataIO.intToLong(0x80000000)); + assertTrue(-1L != DataIO.intToLong(-1)); + } + + @Test public void shift(){ + for(int i =0; i<30;i++){ + assertEquals(i, DataIO.shift(1<2) + assertEquals(i, DataIO.shift(nextPowTwo((1<= 0; valueToPut = random.nextInt(2) + valueToPut * 2) { + byte[] buffer = new byte[20]; + DataIO.putLong(buffer, 2, valueToPut); + long returned = DataIO.getLong(buffer, 2); + assertEquals("The value that was put and the value returned from getLong do not match", valueToPut, returned); + DataIO.putLong(buffer, 2, -valueToPut); + returned = DataIO.getLong(buffer, 2); + assertEquals("The value that was put and the value returned from getLong do not match", -valueToPut, returned); + } + } + + + @Test(expected = EOFException.class) + public void testReadFully_throws_exception_if_not_enough_data() throws IOException { + InputStream inputStream = new ByteArrayInputStream(new byte[0]); + DataIO.readFully(inputStream, new byte[1]); + fail("An EOFException should have occurred by now since there are not enough bytes to read from the InputStream"); + } + + @Test public void testReadFully_with_too_much_data() throws IOException { + byte[] inputBuffer = new byte[] { 1, 2, 3, 4 }; + InputStream in = new ByteArrayInputStream(inputBuffer); + byte[] outputBuffer = new byte[3]; + DataIO.readFully(in, outputBuffer); + byte[] expected = new byte[] { 1, 2, 3 }; + assertArrayEquals("The passed buffer should be filled with the first three bytes read from the InputStream", + expected, outputBuffer); + } + + @Test public void testReadFully_with_data_length_same_as_buffer_length() throws IOException { + byte[] inputBuffer = new byte[] { 1, 2, 3, 4 }; + InputStream in = new ByteArrayInputStream(inputBuffer); + byte[] outputBuffer = new byte[4]; + DataIO.readFully(in, outputBuffer); + assertArrayEquals("The passed buffer should be filled with the whole content of the InputStream" + + " since the buffer length is exactly same as the data length", inputBuffer, outputBuffer); + } + + + @Test public void testPackLong_WithStreams() throws IOException{ + for (long valueToPack = 0; valueToPack < Long.MAX_VALUE + && valueToPack >= 0; valueToPack = random.nextInt(2) + valueToPack * 2) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + DataIO.packLong(outputStream, valueToPack); + DataIO.packLong(outputStream, -valueToPack); + ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); + long unpackedLong = DataIO.unpackLong(inputStream); + assertEquals("Packed and unpacked values do not match", valueToPack, unpackedLong); + unpackedLong = DataIO.unpackLong(inputStream); + assertEquals("Packed and unpacked values do not match", -valueToPack, unpackedLong); + } + } + + @Test(expected = EOFException.class) + public void testUnpackLong_withInputStream_throws_exception_when_stream_is_empty() throws IOException { + DataIO.unpackLong(new ByteArrayInputStream(new byte[0])); + fail("An EOFException should have occurred by now since there are no bytes to read from the InputStream"); + } + + @Test public void testPackLongSize() { + assertEquals("packLongSize should have returned 1 since number 1 can be represented using 1 byte when packed", + 1, DataIO.packLongSize(1)); + assertEquals("packLongSize should have returned 2 since 1 << 7 can be represented using 2 bytes when packed", 2, + DataIO.packLongSize(1 << 7)); + assertEquals("packLongSize should have returned 10 since 1 << 63 can be represented using 10 bytes when packed", 10, + DataIO.packLongSize(1 << 63)); + } + +} \ No newline at end of file diff --git a/src/test/java/org/mapdb/jsr166Tests/BlockingQueueTest.java b/src/test/java/org/mapdb/jsr166Tests/BlockingQueueTest.java new file mode 100644 index 000000000..f7eb600c6 --- /dev/null +++ b/src/test/java/org/mapdb/jsr166Tests/BlockingQueueTest.java @@ -0,0 +1,357 @@ +package org.mapdb.jsr166Tests;/* + * Written by Doug Lea and Martin Buchholz with assistance from members + * of JCP JSR-166 Expert Group and released to the public domain, as + * explained at http://creativecommons.org/publicdomain/zero/1.0/ + * + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Queue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +/** + * Contains "contract" tests applicable to all BlockingQueue implementations. + */ +public abstract class BlockingQueueTest extends JSR166TestCase { + //---------------------------------------------------------------- + // Configuration methods + //---------------------------------------------------------------- + + /** Returns an empty instance of the implementation class. */ + protected abstract BlockingQueue emptyCollection(); + + /** + * Returns an element suitable for insertion in the collection. + * Override for collections with unusual element types. + */ + protected Object makeElement(int i) { + return Integer.valueOf(i); + } + + //---------------------------------------------------------------- + // Tests + //---------------------------------------------------------------- + + /** + * offer(null) throws NullPointerException + */ + public void testOfferNull() { + final Queue q = emptyCollection(); + try { + q.offer(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * add(null) throws NullPointerException + */ + public void testAddNull() { + final Collection q = emptyCollection(); + try { + q.add(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * timed offer(null) throws NullPointerException + */ + public void testTimedOfferNull() throws InterruptedException { + final BlockingQueue q = emptyCollection(); + long startTime = System.nanoTime(); + try { + q.offer(null, LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (NullPointerException success) {} + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + } + + /** + * put(null) throws NullPointerException + */ + public void testPutNull() throws InterruptedException { + final BlockingQueue q = emptyCollection(); + try { + q.put(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * addAll(null) throws NullPointerException + */ + public void testAddAllNull() throws InterruptedException { + final Collection q = emptyCollection(); + try { + q.addAll(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * addAll of a collection with null elements throws NullPointerException + */ + public void testAddAllNullElements() { + final Collection q = emptyCollection(); + final Collection elements = Arrays.asList(new Integer[SIZE]); + try { + q.addAll(elements); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * toArray(null) throws NullPointerException + */ + public void testToArray_NullArray() { + final Collection q = emptyCollection(); + try { + q.toArray((Object[]) null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * drainTo(null) throws NullPointerException + */ + public void testDrainToNull() { + final BlockingQueue q = emptyCollection(); + try { + q.drainTo(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * drainTo(this) throws IllegalArgumentException + */ + public void testDrainToSelf() { + final BlockingQueue q = emptyCollection(); + try { + q.drainTo(q); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } + + /** + * drainTo(null, n) throws NullPointerException + */ + public void testDrainToNullN() { + final BlockingQueue q = emptyCollection(); + try { + q.drainTo(null, 0); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * drainTo(this, n) throws IllegalArgumentException + */ + public void testDrainToSelfN() { + final BlockingQueue q = emptyCollection(); + try { + q.drainTo(q, 0); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } + + /** + * drainTo(c, n) returns 0 and does nothing when n <= 0 + */ + public void testDrainToNonPositiveMaxElements() { + final BlockingQueue q = emptyCollection(); + final int[] ns = { 0, -1, -42, Integer.MIN_VALUE }; + final ArrayList sink = new ArrayList(); + for (int n : ns) { + assertEquals(0, q.drainTo(sink, n)); + assertTrue(sink.isEmpty()); + } + if (q.remainingCapacity() > 0) { + // Not SynchronousQueue, that is + Object one = makeElement(1); + q.add(one); + for (int n : ns) + assertEquals(0, q.drainTo(sink, n)); + assertEquals(1, q.size()); + assertEquals(one, q.poll()); + assertTrue(sink.isEmpty()); + } + } + + /** + * timed poll before a delayed offer times out; after offer succeeds; + * on interruption throws + */ + public void testTimedPollWithOffer() throws InterruptedException { + final BlockingQueue q = emptyCollection(); + final CheckedBarrier barrier = new CheckedBarrier(2); + final Object zero = makeElement(0); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + long startTime = System.nanoTime(); + assertNull(q.poll(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + + barrier.await(); + + assertEquals(zero, q.poll(LONG_DELAY_MS, MILLISECONDS)); + + Thread.currentThread().interrupt(); + try { + q.poll(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + barrier.await(); + try { + q.poll(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + }}); + + barrier.await(); + long startTime = System.nanoTime(); + assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + + barrier.await(); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * take() blocks interruptibly when empty + */ + public void testTakeFromEmptyBlocksInterruptibly() { + final BlockingQueue q = emptyCollection(); + final CountDownLatch threadStarted = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + threadStarted.countDown(); + try { + q.take(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(threadStarted); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * take() throws InterruptedException immediately if interrupted + * before waiting + */ + public void testTakeFromEmptyAfterInterrupt() { + final BlockingQueue q = emptyCollection(); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + Thread.currentThread().interrupt(); + try { + q.take(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + awaitTermination(t); + } + + /** + * timed poll() blocks interruptibly when empty + */ + public void testTimedPollFromEmptyBlocksInterruptibly() { + final BlockingQueue q = emptyCollection(); + final CountDownLatch threadStarted = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + threadStarted.countDown(); + try { + q.poll(2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(threadStarted); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * timed poll() throws InterruptedException immediately if + * interrupted before waiting + */ + public void testTimedPollFromEmptyAfterInterrupt() { + final BlockingQueue q = emptyCollection(); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + Thread.currentThread().interrupt(); + try { + q.poll(2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + awaitTermination(t); + } + + /** + * remove(x) removes x and returns true if present + */ + public void testRemoveElement() { + final BlockingQueue q = emptyCollection(); + final int size = Math.min(q.remainingCapacity(), SIZE); + final Object[] elts = new Object[size]; + assertFalse(q.contains(makeElement(99))); + assertFalse(q.remove(makeElement(99))); + checkEmpty(q); + for (int i = 0; i < size; i++) + q.add(elts[i] = makeElement(i)); + for (int i = 1; i < size; i += 2) { + for (int pass = 0; pass < 2; pass++) { + assertEquals((pass == 0), q.contains(elts[i])); + assertEquals((pass == 0), q.remove(elts[i])); + assertFalse(q.contains(elts[i])); + assertTrue(q.contains(elts[i - 1])); + if (i < size - 1) + assertTrue(q.contains(elts[i + 1])); + } + } + if (size > 0) + assertTrue(q.contains(elts[0])); + for (int i = size - 2; i >= 0; i -= 2) { + assertTrue(q.contains(elts[i])); + assertFalse(q.contains(elts[i + 1])); + assertTrue(q.remove(elts[i])); + assertFalse(q.contains(elts[i])); + assertFalse(q.remove(elts[i + 1])); + assertFalse(q.contains(elts[i + 1])); + } + checkEmpty(q); + } + + /** For debugging. */ + public void XXXXtestFails() { + fail(emptyCollection().getClass().toString()); + } + +} diff --git a/src/test/java/org/mapdb/jsr166Tests/Collection8Test.java b/src/test/java/org/mapdb/jsr166Tests/Collection8Test.java new file mode 100644 index 000000000..90b645ba9 --- /dev/null +++ b/src/test/java/org/mapdb/jsr166Tests/Collection8Test.java @@ -0,0 +1,953 @@ +package org.mapdb.jsr166Tests;/* + * Written by Doug Lea and Martin Buchholz with assistance from + * members of JCP JSR-166 Expert Group and released to the public + * domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import junit.framework.Test; + +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +/** + * Contains tests applicable to all jdk8+ Collection implementations. + * An extension of CollectionTest. + */ +public abstract class Collection8Test extends JSR166TestCase { + final CollectionImplementation impl; + + /** Tests are parameterized by a Collection implementation. */ + Collection8Test(CollectionImplementation impl, String methodName) { + super(methodName); + this.impl = impl; + } + + public static Test testSuite(CollectionImplementation impl) { + return parameterizedTestSuite(Collection8Test.class, + CollectionImplementation.class, + impl); + } + + Object bomb() { + return new Object() { + @Override public boolean equals(Object x) { throw new AssertionError(); } + @Override public int hashCode() { throw new AssertionError(); } + @Override public String toString() { throw new AssertionError(); } + }; + } + + /** Checks properties of empty collections. */ + public void testEmptyMeansEmpty() throws Throwable { + Collection c = impl.emptyCollection(); + emptyMeansEmpty(c); + + if (c instanceof java.io.Serializable) { + try { + emptyMeansEmpty(serialClonePossiblyFailing(c)); + } catch (java.io.NotSerializableException ex) { + // excusable when we have a serializable wrapper around + // a non-serializable collection, as can happen with: + // Vector.subList() => wrapped AbstractList$RandomAccessSubList + if (testImplementationDetails + && (! c.getClass().getName().matches( + "java.util.Collections.*"))) + throw ex; + } + } + + Collection clone = cloneableClone(c); + if (clone != null) + emptyMeansEmpty(clone); + } + + void emptyMeansEmpty(Collection c) throws InterruptedException { + assertTrue(c.isEmpty()); + assertEquals(0, c.size()); + assertEquals("[]", c.toString()); + if (c instanceof List) { + List x = (List) c; + assertEquals(1, x.hashCode()); + assertEquals(x, Collections.emptyList()); + assertEquals(Collections.emptyList(), x); + assertEquals(-1, x.indexOf(impl.makeElement(86))); + assertEquals(-1, x.lastIndexOf(impl.makeElement(99))); + assertThrows( + IndexOutOfBoundsException.class, + () -> x.get(0), + () -> x.set(0, impl.makeElement(42))); + } + else if (c instanceof Set) { + assertEquals(0, c.hashCode()); + assertEquals(c, Collections.emptySet()); + assertEquals(Collections.emptySet(), c); + } + { + Object[] a = c.toArray(); + assertEquals(0, a.length); + assertSame(Object[].class, a.getClass()); + } + { + Object[] a = new Object[0]; + assertSame(a, c.toArray(a)); + } + { + Integer[] a = new Integer[0]; + assertSame(a, c.toArray(a)); + } + { + Integer[] a = { 1, 2, 3}; + assertSame(a, c.toArray(a)); + assertNull(a[0]); + assertSame(2, a[1]); + assertSame(3, a[2]); + } + assertIteratorExhausted(c.iterator()); + Consumer alwaysThrows = e -> { throw new AssertionError(); }; + c.forEach(alwaysThrows); + c.iterator().forEachRemaining(alwaysThrows); + c.spliterator().forEachRemaining(alwaysThrows); + assertFalse(c.spliterator().tryAdvance(alwaysThrows)); + if (c.spliterator().hasCharacteristics(Spliterator.SIZED)) + assertEquals(0, c.spliterator().estimateSize()); + assertFalse(c.contains(bomb())); + assertFalse(c.remove(bomb())); + if (c instanceof Queue) { + Queue q = (Queue) c; + assertNull(q.peek()); + assertNull(q.poll()); + } + if (c instanceof Deque) { + Deque d = (Deque) c; + assertNull(d.peekFirst()); + assertNull(d.peekLast()); + assertNull(d.pollFirst()); + assertNull(d.pollLast()); + assertIteratorExhausted(d.descendingIterator()); + d.descendingIterator().forEachRemaining(alwaysThrows); + assertFalse(d.removeFirstOccurrence(bomb())); + assertFalse(d.removeLastOccurrence(bomb())); + } + if (c instanceof BlockingQueue) { + BlockingQueue q = (BlockingQueue) c; + assertNull(q.poll(randomExpiredTimeout(), randomTimeUnit())); + } + if (c instanceof BlockingDeque) { + BlockingDeque q = (BlockingDeque) c; + assertNull(q.pollFirst(randomExpiredTimeout(), randomTimeUnit())); + assertNull(q.pollLast(randomExpiredTimeout(), randomTimeUnit())); + } + } + + public void testNullPointerExceptions() throws InterruptedException { + Collection c = impl.emptyCollection(); + assertThrows( + NullPointerException.class, + () -> c.addAll(null), + () -> c.containsAll(null), + () -> c.retainAll(null), + () -> c.removeAll(null), + () -> c.removeIf(null), + () -> c.forEach(null), + () -> c.iterator().forEachRemaining(null), + () -> c.spliterator().forEachRemaining(null), + () -> c.spliterator().tryAdvance(null), + () -> c.toArray((Object[]) null)); + + if (!impl.permitsNulls()) { + assertThrows( + NullPointerException.class, + () -> c.add(null)); + } + if (!impl.permitsNulls() && c instanceof Queue) { + Queue q = (Queue) c; + assertThrows( + NullPointerException.class, + () -> q.offer(null)); + } + if (!impl.permitsNulls() && c instanceof Deque) { + Deque d = (Deque) c; + assertThrows( + NullPointerException.class, + () -> d.addFirst(null), + () -> d.addLast(null), + () -> d.offerFirst(null), + () -> d.offerLast(null), + () -> d.push(null), + () -> d.descendingIterator().forEachRemaining(null)); + } + if (c instanceof BlockingQueue) { + BlockingQueue q = (BlockingQueue) c; + assertThrows( + NullPointerException.class, + () -> { + try { q.offer(null, 1L, HOURS); } + catch (InterruptedException ex) { + throw new AssertionError(ex); + }}, + () -> { + try { q.put(null); } + catch (InterruptedException ex) { + throw new AssertionError(ex); + }}); + } + if (c instanceof BlockingDeque) { + BlockingDeque q = (BlockingDeque) c; + assertThrows( + NullPointerException.class, + () -> { + try { q.offerFirst(null, 1L, HOURS); } + catch (InterruptedException ex) { + throw new AssertionError(ex); + }}, + () -> { + try { q.offerLast(null, 1L, HOURS); } + catch (InterruptedException ex) { + throw new AssertionError(ex); + }}, + () -> { + try { q.putFirst(null); } + catch (InterruptedException ex) { + throw new AssertionError(ex); + }}, + () -> { + try { q.putLast(null); } + catch (InterruptedException ex) { + throw new AssertionError(ex); + }}); + } + } + + public void testNoSuchElementExceptions() { + Collection c = impl.emptyCollection(); + assertThrows( + NoSuchElementException.class, + () -> c.iterator().next()); + + if (c instanceof Queue) { + Queue q = (Queue) c; + assertThrows( + NoSuchElementException.class, + () -> q.element(), + () -> q.remove()); + } + if (c instanceof Deque) { + Deque d = (Deque) c; + assertThrows( + NoSuchElementException.class, + () -> d.getFirst(), + () -> d.getLast(), + () -> d.removeFirst(), + () -> d.removeLast(), + () -> d.pop(), + () -> d.descendingIterator().next()); + } + if (c instanceof List) { + List x = (List) c; + assertThrows( + NoSuchElementException.class, + () -> x.iterator().next(), + () -> x.listIterator().next(), + () -> x.listIterator(0).next(), + () -> x.listIterator().previous(), + () -> x.listIterator(0).previous()); + } + } + + public void testRemoveIf() { + Collection c = impl.emptyCollection(); + boolean ordered = + c.spliterator().hasCharacteristics(Spliterator.ORDERED); + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + int n = rnd.nextInt(6); + for (int i = 0; i < n; i++) c.add(impl.makeElement(i)); + AtomicReference threwAt = new AtomicReference(null); + List orig = rnd.nextBoolean() + ? new ArrayList(c) + : Arrays.asList(c.toArray()); + + // Merely creating an iterator can change ArrayBlockingQueue behavior + Iterator it = rnd.nextBoolean() ? c.iterator() : null; + + ArrayList survivors = new ArrayList(); + ArrayList accepts = new ArrayList(); + ArrayList rejects = new ArrayList(); + + Predicate randomPredicate = e -> { + assertNull(threwAt.get()); + switch (rnd.nextInt(3)) { + case 0: accepts.add(e); return true; + case 1: rejects.add(e); return false; + case 2: threwAt.set(e); throw new ArithmeticException(); + default: throw new AssertionError(); + } + }; + try { + try { + boolean modified = c.removeIf(randomPredicate); + assertNull(threwAt.get()); + assertEquals(modified, accepts.size() > 0); + assertEquals(modified, rejects.size() != n); + assertEquals(accepts.size() + rejects.size(), n); + if (ordered) { + assertEquals(rejects, + Arrays.asList(c.toArray())); + } else { + assertEquals(new HashSet(rejects), + new HashSet(Arrays.asList(c.toArray()))); + } + } catch (ArithmeticException ok) { + assertNotNull(threwAt.get()); + assertTrue(c.contains(threwAt.get())); + } + if (it != null && impl.isConcurrent()) + // check for weakly consistent iterator + while (it.hasNext()) assertTrue(orig.contains(it.next())); + switch (rnd.nextInt(4)) { + case 0: survivors.addAll(c); break; + case 1: survivors.addAll(Arrays.asList(c.toArray())); break; + case 2: c.forEach(survivors::add); break; + case 3: for (Object e : c) survivors.add(e); break; + } + assertTrue(orig.containsAll(accepts)); + assertTrue(orig.containsAll(rejects)); + assertTrue(orig.containsAll(survivors)); + assertTrue(orig.containsAll(c)); + assertTrue(c.containsAll(rejects)); + assertTrue(c.containsAll(survivors)); + assertTrue(survivors.containsAll(rejects)); + if (threwAt.get() == null) { + assertEquals(n - accepts.size(), c.size()); + for (Object x : accepts) assertFalse(c.contains(x)); + } else { + // Two acceptable behaviors: entire removeIf call is one + // transaction, or each element processed is one transaction. + assertTrue(n == c.size() || n == c.size() + accepts.size()); + int k = 0; + for (Object x : accepts) if (c.contains(x)) k++; + assertTrue(k == accepts.size() || k == 0); + } + } catch (Throwable ex) { + System.err.println(impl.klazz()); + // c is at risk of corruption if we got here, so be lenient + try { System.err.printf("c=%s%n", c); } + catch (Throwable t) { t.printStackTrace(); } + System.err.printf("n=%d%n", n); + System.err.printf("orig=%s%n", orig); + System.err.printf("accepts=%s%n", accepts); + System.err.printf("rejects=%s%n", rejects); + System.err.printf("survivors=%s%n", survivors); + System.err.printf("threwAt=%s%n", threwAt.get()); + throw ex; + } + } + + /** + * All elements removed in the middle of CONCURRENT traversal. + */ + public void testElementRemovalDuringTraversal() { + Collection c = impl.emptyCollection(); + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + int n = rnd.nextInt(6); + ArrayList copy = new ArrayList(); + for (int i = 0; i < n; i++) { + Object x = impl.makeElement(i); + copy.add(x); + c.add(x); + } + ArrayList iterated = new ArrayList(); + ArrayList spliterated = new ArrayList(); + Spliterator s = c.spliterator(); + Iterator it = c.iterator(); + for (int i = rnd.nextInt(n + 1); --i >= 0; ) { + assertTrue(s.tryAdvance(spliterated::add)); + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + iterated.add(it.next()); + } + Consumer alwaysThrows = e -> { throw new AssertionError(); }; + if (s.hasCharacteristics(Spliterator.CONCURRENT)) { + c.clear(); + if (testImplementationDetails + && !(c instanceof java.util.concurrent.ArrayBlockingQueue)) { + if (rnd.nextBoolean()) + assertFalse(s.tryAdvance(alwaysThrows)); + else + s.forEachRemaining(alwaysThrows); + } + if (it.hasNext()) iterated.add(it.next()); + if (rnd.nextBoolean()) assertIteratorExhausted(it); + } + assertTrue(copy.containsAll(iterated)); + assertTrue(copy.containsAll(spliterated)); + } + + /** + * Some elements randomly disappear in the middle of traversal. + */ + public void testRandomElementRemovalDuringTraversal() { + Collection c = impl.emptyCollection(); + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + int n = rnd.nextInt(6); + ArrayList copy = new ArrayList(); + for (int i = 0; i < n; i++) { + Object x = impl.makeElement(i); + copy.add(x); + c.add(x); + } + ArrayList iterated = new ArrayList(); + ArrayList spliterated = new ArrayList(); + ArrayList removed = new ArrayList(); + Spliterator s = c.spliterator(); + Iterator it = c.iterator(); + if (! (s.hasCharacteristics(Spliterator.CONCURRENT) || + s.hasCharacteristics(Spliterator.IMMUTABLE))) + return; + for (int i = rnd.nextInt(n + 1); --i >= 0; ) { + assertTrue(s.tryAdvance(e -> {})); + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + it.next(); + } + Consumer alwaysThrows = e -> { throw new AssertionError(); }; + if (rnd.nextBoolean()) { + for (Iterator z = c.iterator(); z.hasNext(); ) { + Object e = z.next(); + if (rnd.nextBoolean()) { + try { + z.remove(); + } catch (UnsupportedOperationException ok) { return; } + removed.add(e); + } + } + } else { + Predicate randomlyRemove = e -> { + if (rnd.nextBoolean()) { removed.add(e); return true; } + else return false; + }; + c.removeIf(randomlyRemove); + } + s.forEachRemaining(spliterated::add); + while (it.hasNext()) + iterated.add(it.next()); + assertTrue(copy.containsAll(iterated)); + assertTrue(copy.containsAll(spliterated)); + assertTrue(copy.containsAll(removed)); + if (s.hasCharacteristics(Spliterator.CONCURRENT)) { + ArrayList iteratedAndRemoved = new ArrayList(iterated); + ArrayList spliteratedAndRemoved = new ArrayList(spliterated); + iteratedAndRemoved.retainAll(removed); + spliteratedAndRemoved.retainAll(removed); + assertTrue(iteratedAndRemoved.size() <= 1); + assertTrue(spliteratedAndRemoved.size() <= 1); + if (testImplementationDetails + && !(c instanceof java.util.concurrent.ArrayBlockingQueue)) + assertTrue(spliteratedAndRemoved.isEmpty()); + } + } + + /** + * Various ways of traversing a collection yield same elements + */ + public void testTraversalEquivalence() { + Collection c = impl.emptyCollection(); + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + int n = rnd.nextInt(6); + for (int i = 0; i < n; i++) c.add(impl.makeElement(i)); + ArrayList iterated = new ArrayList(); + ArrayList iteratedForEachRemaining = new ArrayList(); + ArrayList tryAdvanced = new ArrayList(); + ArrayList spliterated = new ArrayList(); + ArrayList splitonced = new ArrayList(); + ArrayList forEached = new ArrayList(); + ArrayList streamForEached = new ArrayList(); + ConcurrentLinkedQueue parallelStreamForEached = new ConcurrentLinkedQueue(); + ArrayList removeIfed = new ArrayList(); + for (Object x : c) iterated.add(x); + c.iterator().forEachRemaining(iteratedForEachRemaining::add); + for (Spliterator s = c.spliterator(); + s.tryAdvance(tryAdvanced::add); ) {} + c.spliterator().forEachRemaining(spliterated::add); + { // trySplit returns "strict prefix" + Spliterator s1 = c.spliterator(), s2 = s1.trySplit(); + if (s2 != null) s2.forEachRemaining(splitonced::add); + s1.forEachRemaining(splitonced::add); + } + c.forEach(forEached::add); + c.stream().forEach(streamForEached::add); + c.parallelStream().forEach(parallelStreamForEached::add); + c.removeIf(e -> { removeIfed.add(e); return false; }); + boolean ordered = + c.spliterator().hasCharacteristics(Spliterator.ORDERED); + if (c instanceof List || c instanceof Deque) + assertTrue(ordered); + HashSet cset = new HashSet(c); + assertEquals(cset, new HashSet(parallelStreamForEached)); + if (ordered) { + assertEquals(iterated, iteratedForEachRemaining); + assertEquals(iterated, tryAdvanced); + assertEquals(iterated, spliterated); + assertEquals(iterated, splitonced); + assertEquals(iterated, forEached); + assertEquals(iterated, streamForEached); + assertEquals(iterated, removeIfed); + } else { + assertEquals(cset, new HashSet(iterated)); + assertEquals(cset, new HashSet(iteratedForEachRemaining)); + assertEquals(cset, new HashSet(tryAdvanced)); + assertEquals(cset, new HashSet(spliterated)); + assertEquals(cset, new HashSet(splitonced)); + assertEquals(cset, new HashSet(forEached)); + assertEquals(cset, new HashSet(streamForEached)); + assertEquals(cset, new HashSet(removeIfed)); + } + if (c instanceof Deque) { + Deque d = (Deque) c; + ArrayList descending = new ArrayList(); + ArrayList descendingForEachRemaining = new ArrayList(); + for (Iterator it = d.descendingIterator(); it.hasNext(); ) + descending.add(it.next()); + d.descendingIterator().forEachRemaining( + e -> descendingForEachRemaining.add(e)); + Collections.reverse(descending); + Collections.reverse(descendingForEachRemaining); + assertEquals(iterated, descending); + assertEquals(iterated, descendingForEachRemaining); + } + } + + /** + * Iterator.forEachRemaining has same behavior as Iterator's + * default implementation. + */ + public void testForEachRemainingConsistentWithDefaultImplementation() { + Collection c = impl.emptyCollection(); + if (!testImplementationDetails + || c.getClass() == java.util.LinkedList.class) + return; + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + int n = 1 + rnd.nextInt(3); + for (int i = 0; i < n; i++) c.add(impl.makeElement(i)); + ArrayList iterated = new ArrayList(); + ArrayList iteratedForEachRemaining = new ArrayList(); + Iterator it1 = c.iterator(); + Iterator it2 = c.iterator(); + assertTrue(it1.hasNext()); + assertTrue(it2.hasNext()); + c.clear(); + Object r1, r2; + try { + while (it1.hasNext()) iterated.add(it1.next()); + r1 = iterated; + } catch (ConcurrentModificationException ex) { + r1 = ConcurrentModificationException.class; + assertFalse(impl.isConcurrent()); + } + try { + it2.forEachRemaining(iteratedForEachRemaining::add); + r2 = iteratedForEachRemaining; + } catch (ConcurrentModificationException ex) { + r2 = ConcurrentModificationException.class; + assertFalse(impl.isConcurrent()); + } + assertEquals(r1, r2); + } + + /** + * Calling Iterator#remove() after Iterator#forEachRemaining + * should (maybe) remove last element + */ + public void testRemoveAfterForEachRemaining() { + Collection c = impl.emptyCollection(); + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + ArrayList copy = new ArrayList(); + boolean ordered = c.spliterator().hasCharacteristics(Spliterator.ORDERED); + testCollection: { + int n = 3 + rnd.nextInt(2); + for (int i = 0; i < n; i++) { + Object x = impl.makeElement(i); + c.add(x); + copy.add(x); + } + Iterator it = c.iterator(); + if (ordered) { + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + assertEquals(impl.makeElement(0), it.next()); + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + assertEquals(impl.makeElement(1), it.next()); + } else { + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + assertTrue(copy.contains(it.next())); + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + assertTrue(copy.contains(it.next())); + } + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + it.forEachRemaining( + e -> { + assertTrue(c.contains(e)); + assertTrue(copy.contains(e));}); + if (testImplementationDetails) { + if (c instanceof java.util.concurrent.ArrayBlockingQueue) { + assertIteratorExhausted(it); + } else { + try { it.remove(); } + catch (UnsupportedOperationException ok) { + break testCollection; + } + assertEquals(n - 1, c.size()); + if (ordered) { + for (int i = 0; i < n - 1; i++) + assertTrue(c.contains(impl.makeElement(i))); + assertFalse(c.contains(impl.makeElement(n - 1))); + } + } + } + } + if (c instanceof Deque) { + Deque d = (Deque) impl.emptyCollection(); + assertTrue(ordered); + int n = 3 + rnd.nextInt(2); + for (int i = 0; i < n; i++) d.add(impl.makeElement(i)); + Iterator it = d.descendingIterator(); + assertTrue(it.hasNext()); + assertEquals(impl.makeElement(n - 1), it.next()); + assertTrue(it.hasNext()); + assertEquals(impl.makeElement(n - 2), it.next()); + it.forEachRemaining(e -> assertTrue(c.contains(e))); + if (testImplementationDetails) { + it.remove(); + assertEquals(n - 1, d.size()); + for (int i = 1; i < n; i++) + assertTrue(d.contains(impl.makeElement(i))); + assertFalse(d.contains(impl.makeElement(0))); + } + } + } + + /** + * stream().forEach returns elements in the collection + */ + public void testStreamForEach() throws Throwable { + final Collection c = impl.emptyCollection(); + final AtomicLong count = new AtomicLong(0L); + final Object x = impl.makeElement(1); + final Object y = impl.makeElement(2); + final ArrayList found = new ArrayList(); + Consumer spy = o -> found.add(o); + c.stream().forEach(spy); + assertTrue(found.isEmpty()); + + assertTrue(c.add(x)); + c.stream().forEach(spy); + assertEquals(Collections.singletonList(x), found); + found.clear(); + + assertTrue(c.add(y)); + c.stream().forEach(spy); + assertEquals(2, found.size()); + assertTrue(found.contains(x)); + assertTrue(found.contains(y)); + found.clear(); + + c.clear(); + c.stream().forEach(spy); + assertTrue(found.isEmpty()); + } + + public void testStreamForEachConcurrentStressTest() throws Throwable { + if (!impl.isConcurrent()) return; + final Collection c = impl.emptyCollection(); + final long testDurationMillis = timeoutMillis(); + final AtomicBoolean done = new AtomicBoolean(false); + final Object elt = impl.makeElement(1); + final Future f1, f2; + final ExecutorService pool = Executors.newCachedThreadPool(); + try (PoolCleaner cleaner = cleaner(pool, done)) { + final CountDownLatch threadsStarted = new CountDownLatch(2); + Runnable checkElt = () -> { + threadsStarted.countDown(); + while (!done.get()) + c.stream().forEach(x -> assertSame(x, elt)); }; + Runnable addRemove = () -> { + threadsStarted.countDown(); + while (!done.get()) { + assertTrue(c.add(elt)); + assertTrue(c.remove(elt)); + }}; + f1 = pool.submit(checkElt); + f2 = pool.submit(addRemove); + Thread.sleep(testDurationMillis); + } + assertNull(f1.get(0L, MILLISECONDS)); + assertNull(f2.get(0L, MILLISECONDS)); + } + + /** + * collection.forEach returns elements in the collection + */ + public void testForEach() throws Throwable { + final Collection c = impl.emptyCollection(); + final AtomicLong count = new AtomicLong(0L); + final Object x = impl.makeElement(1); + final Object y = impl.makeElement(2); + final ArrayList found = new ArrayList(); + Consumer spy = o -> found.add(o); + c.forEach(spy); + assertTrue(found.isEmpty()); + + assertTrue(c.add(x)); + c.forEach(spy); + assertEquals(Collections.singletonList(x), found); + found.clear(); + + assertTrue(c.add(y)); + c.forEach(spy); + assertEquals(2, found.size()); + assertTrue(found.contains(x)); + assertTrue(found.contains(y)); + found.clear(); + + c.clear(); + c.forEach(spy); + assertTrue(found.isEmpty()); + } + + static T chooseOne(T ... ts) { + return ts[ThreadLocalRandom.current().nextInt(ts.length)]; + } + + static Runnable adderRemover(Collection c, E e) { + return chooseOne( + () -> { + assertTrue(c.add(e)); + assertTrue(c.contains(e)); + assertTrue(c.remove(e)); + assertFalse(c.contains(e)); + }, + () -> { + assertTrue(c.add(e)); + assertTrue(c.contains(e)); + assertTrue(c.removeIf(x -> x == e)); + assertFalse(c.contains(e)); + }, + () -> { + assertTrue(c.add(e)); + assertTrue(c.contains(e)); + for (Iterator it = c.iterator();; ) + if (it.next() == e) { + try { it.remove(); } + catch (UnsupportedOperationException ok) { + c.remove(e); + } + break; + } + assertFalse(c.contains(e)); + }); + } + + /** + * Concurrent Spliterators, once exhausted, stay exhausted. + */ + public void testStickySpliteratorExhaustion() throws Throwable { + if (!impl.isConcurrent()) return; + if (!testImplementationDetails) return; + final ThreadLocalRandom rnd = ThreadLocalRandom.current(); + final Consumer alwaysThrows = e -> { throw new AssertionError(); }; + final Collection c = impl.emptyCollection(); + final Spliterator s = c.spliterator(); + if (rnd.nextBoolean()) { + assertFalse(s.tryAdvance(alwaysThrows)); + } else { + s.forEachRemaining(alwaysThrows); + } + final Object one = impl.makeElement(1); + // Spliterator should not notice added element + c.add(one); + if (rnd.nextBoolean()) { + assertFalse(s.tryAdvance(alwaysThrows)); + } else { + s.forEachRemaining(alwaysThrows); + } + } + + /** + * Motley crew of threads concurrently randomly hammer the collection. + */ + public void testDetectRaces() throws Throwable { + if (!impl.isConcurrent()) return; + final ThreadLocalRandom rnd = ThreadLocalRandom.current(); + final Collection c = impl.emptyCollection(); + final long testDurationMillis + = expensiveTests ? LONG_DELAY_MS : timeoutMillis(); + final AtomicBoolean done = new AtomicBoolean(false); + final Object one = impl.makeElement(1); + final Object two = impl.makeElement(2); + final Consumer checkSanity = x -> assertTrue(x == one || x == two); + final Consumer checkArraySanity = array -> { + // assertTrue(array.length <= 2); // duplicates are permitted + for (Object x : array) assertTrue(x == one || x == two); + }; + final Object[] emptyArray = + (Object[]) java.lang.reflect.Array.newInstance(one.getClass(), 0); + final List> futures; + final Phaser threadsStarted = new Phaser(1); // register this thread + final Runnable[] frobbers = { + () -> c.forEach(checkSanity), + () -> c.stream().forEach(checkSanity), + () -> c.parallelStream().forEach(checkSanity), + () -> c.spliterator().trySplit(), + () -> { + Spliterator s = c.spliterator(); + s.tryAdvance(checkSanity); + s.trySplit(); + }, + () -> { + Spliterator s = c.spliterator(); + do {} while (s.tryAdvance(checkSanity)); + }, + () -> { for (Object x : c) checkSanity.accept(x); }, + () -> checkArraySanity.accept(c.toArray()), + () -> checkArraySanity.accept(c.toArray(emptyArray)), + () -> { + Object[] a = new Object[5]; + Object three = impl.makeElement(3); + Arrays.fill(a, 0, a.length, three); + Object[] x = c.toArray(a); + if (x == a) + for (int i = 0; i < a.length && a[i] != null; i++) + checkSanity.accept(a[i]); + // A careful reading of the spec does not support: + // for (i++; i < a.length; i++) assertSame(three, a[i]); + else + checkArraySanity.accept(x); + }, + adderRemover(c, one), + adderRemover(c, two), + }; + final List tasks = + Arrays.stream(frobbers) + .filter(task -> rnd.nextBoolean()) // random subset + .map(task -> (Runnable) () -> { + threadsStarted.arriveAndAwaitAdvance(); + while (!done.get()) + task.run(); + }) + .collect(Collectors.toList()); + final ExecutorService pool = Executors.newCachedThreadPool(); + try (PoolCleaner cleaner = cleaner(pool, done)) { + threadsStarted.bulkRegister(tasks.size()); + futures = tasks.stream() + .map(pool::submit) + .collect(Collectors.toList()); + threadsStarted.arriveAndDeregister(); + Thread.sleep(testDurationMillis); + } + for (Future future : futures) + assertNull(future.get(0L, MILLISECONDS)); + } + + /** + * Spliterators are either IMMUTABLE or truly late-binding or, if + * concurrent, use the same "late-binding style" of returning + * elements added between creation and first use. + */ + public void testLateBindingStyle() { + if (!testImplementationDetails) return; + if (impl.klazz() == ArrayList.class) return; // for jdk8 + // Immutable (snapshot) spliterators are exempt + if (impl.emptyCollection().spliterator() + .hasCharacteristics(Spliterator.IMMUTABLE)) + return; + final Object one = impl.makeElement(1); + { + final Collection c = impl.emptyCollection(); + final Spliterator split = c.spliterator(); + c.add(one); + assertTrue(split.tryAdvance(e -> { assertSame(e, one); })); + assertFalse(split.tryAdvance(e -> { throw new AssertionError(); })); + assertTrue(c.contains(one)); + } + { + final AtomicLong count = new AtomicLong(0); + final Collection c = impl.emptyCollection(); + final Spliterator split = c.spliterator(); + c.add(one); + split.forEachRemaining( + e -> { assertSame(e, one); count.getAndIncrement(); }); + assertEquals(1L, count.get()); + assertFalse(split.tryAdvance(e -> { throw new AssertionError(); })); + assertTrue(c.contains(one)); + } + } + + /** + * Spliterator.getComparator throws IllegalStateException iff the + * spliterator does not report SORTED. + */ + public void testGetComparator_IllegalStateException() { + Collection c = impl.emptyCollection(); + Spliterator s = c.spliterator(); + boolean reportsSorted = s.hasCharacteristics(Spliterator.SORTED); + try { + s.getComparator(); + assertTrue(reportsSorted); + } catch (IllegalStateException ex) { + assertFalse(reportsSorted); + } + } + + public void testCollectionCopies() throws Exception { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + Collection c = impl.emptyCollection(); + for (int n = rnd.nextInt(4); n--> 0; ) + c.add(impl.makeElement(rnd.nextInt())); + assertEquals(c, c); + if (c instanceof List) + assertCollectionsEquals(c, new ArrayList(c)); + else if (c instanceof Set) + assertCollectionsEquals(c, new HashSet(c)); + else if (c instanceof Deque) + assertCollectionsEquivalent(c, new ArrayDeque(c)); + + Collection clone = cloneableClone(c); + if (clone != null) { + assertSame(c.getClass(), clone.getClass()); + assertCollectionsEquivalent(c, clone); + } + try { + Collection serialClone = serialClonePossiblyFailing(c); + assertSame(c.getClass(), serialClone.getClass()); + assertCollectionsEquivalent(c, serialClone); + } catch (java.io.NotSerializableException acceptable) {} + } + + public void testReplaceAllIsNotStructuralModification() { + Collection c = impl.emptyCollection(); + if (!(c instanceof List)) + return; + List list = (List) c; + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + for (int n = rnd.nextInt(2, 10); n--> 0; ) + list.add(impl.makeElement(rnd.nextInt())); + ArrayList copy = new ArrayList(list); + int size = list.size(), half = size / 2; + Iterator it = list.iterator(); + for (int i = 0; i < half; i++) + assertEquals(it.next(), copy.get(i)); + list.replaceAll(n -> n); + // ConcurrentModificationException must not be thrown here. + for (int i = half; i < size; i++) + assertEquals(it.next(), copy.get(i)); + } + +// public void testCollection8DebugFail() { +// fail(impl.klazz().getSimpleName()); +// } +} diff --git a/src/test/java/org/mapdb/jsr166Tests/CollectionImplementation.java b/src/test/java/org/mapdb/jsr166Tests/CollectionImplementation.java new file mode 100644 index 000000000..c35f0ebd5 --- /dev/null +++ b/src/test/java/org/mapdb/jsr166Tests/CollectionImplementation.java @@ -0,0 +1,19 @@ +package org.mapdb.jsr166Tests;/* + * Written by Doug Lea and Martin Buchholz with assistance from + * members of JCP JSR-166 Expert Group and released to the public + * domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import java.util.Collection; + +/** Allows tests to work with different Collection implementations. */ +public interface CollectionImplementation { + /** Returns the Collection class. */ + public Class klazz(); + /** Returns an empty collection. */ + public Collection emptyCollection(); + public Object makeElement(int i); + public boolean isConcurrent(); + public boolean permitsNulls(); +} diff --git a/src/test/java/org/mapdb/jsr166Tests/CollectionTest.java b/src/test/java/org/mapdb/jsr166Tests/CollectionTest.java new file mode 100644 index 000000000..4181ed119 --- /dev/null +++ b/src/test/java/org/mapdb/jsr166Tests/CollectionTest.java @@ -0,0 +1,20 @@ +package org.mapdb.jsr166Tests;/* + * Written by Doug Lea and Martin Buchholz with assistance from + * members of JCP JSR-166 Expert Group and released to the public + * domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Contains tests applicable to all Collection implementations. + */ +public abstract class CollectionTest extends JSR166TestCase { + final CollectionImplementation impl; + + /** Tests are parameterized by a Collection implementation. */ + CollectionTest(CollectionImplementation impl, String methodName) { + super(methodName); + this.impl = impl; + } + +} diff --git a/src/test/java/org/mapdb/jsr166Tests/JSR166TestCase.java b/src/test/java/org/mapdb/jsr166Tests/JSR166TestCase.java new file mode 100644 index 000000000..91ffbcd60 --- /dev/null +++ b/src/test/java/org/mapdb/jsr166Tests/JSR166TestCase.java @@ -0,0 +1,1926 @@ +package org.mapdb.jsr166Tests;/* + * Written by Doug Lea and Martin Buchholz with assistance from + * members of JCP JSR-166 Expert Group and released to the public + * domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +/* + * @test + * @summary JSR-166 tck tests, in a number of variations. + * The first is the conformance testing variant, + * while others also test implementation details. + * @build * + * @modules java.management + * @run junit/othervm/timeout=1000 JSR166TestCase + * @run junit/othervm/timeout=1000 + * --add-opens java.base/java.util.concurrent=ALL-UNNAMED + * --add-opens java.base/java.lang=ALL-UNNAMED + * -Djsr166.testImplementationDetails=true + * JSR166TestCase + * @run junit/othervm/timeout=1000 + * --add-opens java.base/java.util.concurrent=ALL-UNNAMED + * --add-opens java.base/java.lang=ALL-UNNAMED + * -Djsr166.testImplementationDetails=true + * -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 + * JSR166TestCase + * @run junit/othervm/timeout=1000 + * --add-opens java.base/java.util.concurrent=ALL-UNNAMED + * --add-opens java.base/java.lang=ALL-UNNAMED + * -Djsr166.testImplementationDetails=true + * -Djava.util.concurrent.ForkJoinPool.common.parallelism=1 + * -Djava.util.secureRandomSeed=true + * JSR166TestCase + * @run junit/othervm/timeout=1000/policy=tck.policy + * --add-opens java.base/java.util.concurrent=ALL-UNNAMED + * --add-opens java.base/java.lang=ALL-UNNAMED + * -Djsr166.testImplementationDetails=true + * JSR166TestCase + */ + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.security.SecurityPermission; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Deque; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.PropertyPermission; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.RecursiveAction; +import java.util.concurrent.RecursiveTask; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.Semaphore; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Pattern; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestResult; +import junit.framework.TestSuite; + +/** + * Base class for JSR166 Junit TCK tests. Defines some constants, + * utility methods and classes, as well as a simple framework for + * helping to make sure that assertions failing in generated threads + * cause the associated test that generated them to itself fail (which + * JUnit does not otherwise arrange). The rules for creating such + * tests are: + * + *
    + * + *
  1. All assertions in code running in generated threads must use + * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link + * #threadAssertEquals}, or {@link #threadAssertNull}, (not + * {@code fail}, {@code assertTrue}, etc.) It is OK (but not + * particularly recommended) for other code to use these forms too. + * Only the most typically used JUnit assertion methods are defined + * this way, but enough to live with. + * + *
  2. If you override {@link #setUp} or {@link #tearDown}, make sure + * to invoke {@code super.setUp} and {@code super.tearDown} within + * them. These methods are used to clear and check for thread + * assertion failures. + * + *
  3. All delays and timeouts must use one of the constants {@code + * SHORT_DELAY_MS}, {@code SMALL_DELAY_MS}, {@code MEDIUM_DELAY_MS}, + * {@code LONG_DELAY_MS}. The idea here is that a SHORT is always + * discriminable from zero time, and always allows enough time for the + * small amounts of computation (creating a thread, calling a few + * methods, etc) needed to reach a timeout point. Similarly, a SMALL + * is always discriminable as larger than SHORT and smaller than + * MEDIUM. And so on. These constants are set to conservative values, + * but even so, if there is ever any doubt, they can all be increased + * in one spot to rerun tests on slower platforms. + * + *
  4. All threads generated must be joined inside each test case + * method (or {@code fail} to do so) before returning from the + * method. The {@code joinPool} method can be used to do this when + * using Executors. + * + *
+ * + *

Other notes + *

    + * + *
  • Usually, there is one testcase method per JSR166 method + * covering "normal" operation, and then as many exception-testing + * methods as there are exceptions the method can throw. Sometimes + * there are multiple tests per JSR166 method when the different + * "normal" behaviors differ significantly. And sometimes testcases + * cover multiple methods when they cannot be tested in isolation. + * + *
  • The documentation style for testcases is to provide as javadoc + * a simple sentence or two describing the property that the testcase + * method purports to test. The javadocs do not say anything about how + * the property is tested. To find out, read the code. + * + *
  • These tests are "conformance tests", and do not attempt to + * test throughput, latency, scalability or other performance factors + * (see the separate "jtreg" tests for a set intended to check these + * for the most central aspects of functionality.) So, most tests use + * the smallest sensible numbers of threads, collection sizes, etc + * needed to check basic conformance. + * + *
  • The test classes currently do not declare inclusion in + * any particular package to simplify things for people integrating + * them in TCK test suites. + * + *
  • As a convenience, the {@code main} of this class (JSR166TestCase) + * runs all JSR166 unit tests. + * + *
+ */ +public abstract class JSR166TestCase extends TestCase { + private static final boolean useSecurityManager = + Boolean.getBoolean("jsr166.useSecurityManager"); + + protected static final boolean expensiveTests = + Boolean.getBoolean("jsr166.expensiveTests"); + + /** + * If true, also run tests that are not part of the official tck + * because they test unspecified implementation details. + */ + protected static final boolean testImplementationDetails = + Boolean.getBoolean("jsr166.testImplementationDetails"); + + /** + * If true, report on stdout all "slow" tests, that is, ones that + * take more than profileThreshold milliseconds to execute. + */ + private static final boolean profileTests = + Boolean.getBoolean("jsr166.profileTests"); + + /** + * The number of milliseconds that tests are permitted for + * execution without being reported, when profileTests is set. + */ + private static final long profileThreshold = + Long.getLong("jsr166.profileThreshold", 100); + + /** + * The number of repetitions per test (for tickling rare bugs). + */ + private static final int runsPerTest = + Integer.getInteger("jsr166.runsPerTest", 1); + + /** + * The number of repetitions of the test suite (for finding leaks?). + */ + private static final int suiteRuns = + Integer.getInteger("jsr166.suiteRuns", 1); + + /** + * Returns the value of the system property, or NaN if not defined. + */ + private static float systemPropertyValue(String name) { + String floatString = System.getProperty(name); + if (floatString == null) + return Float.NaN; + try { + return Float.parseFloat(floatString); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException( + String.format("Bad float value in system property %s=%s", + name, floatString)); + } + } + + /** + * The scaling factor to apply to standard delays used in tests. + * May be initialized from any of: + * - the "jsr166.delay.factor" system property + * - the "test.timeout.factor" system property (as used by jtreg) + * See: http://openjdk.java.net/jtreg/tag-spec.html + * - hard-coded fuzz factor when using a known slowpoke VM + */ + private static final float delayFactor = delayFactor(); + + private static float delayFactor() { + float x; + if (!Float.isNaN(x = systemPropertyValue("jsr166.delay.factor"))) + return x; + if (!Float.isNaN(x = systemPropertyValue("test.timeout.factor"))) + return x; + String prop = System.getProperty("java.vm.version"); + if (prop != null && prop.matches(".*debug.*")) + return 4.0f; // How much slower is fastdebug than product?! + return 1.0f; + } + + public JSR166TestCase() { super(); } + public JSR166TestCase(String name) { super(name); } + + /** + * A filter for tests to run, matching strings of the form + * methodName(className), e.g. "testInvokeAll5(ForkJoinPoolTest)" + * Usefully combined with jsr166.runsPerTest. + */ + private static final Pattern methodFilter = methodFilter(); + + private static Pattern methodFilter() { + String regex = System.getProperty("jsr166.methodFilter"); + return (regex == null) ? null : Pattern.compile(regex); + } + + // Instrumentation to debug very rare, but very annoying hung test runs. + static volatile TestCase currentTestCase; + // static volatile int currentRun = 0; + static { + Runnable checkForWedgedTest = new Runnable() { public void run() { + // Avoid spurious reports with enormous runsPerTest. + // A single test case run should never take more than 1 second. + // But let's cap it at the high end too ... + final int timeoutMinutes = + Math.min(15, Math.max(runsPerTest / 60, 1)); + for (TestCase lastTestCase = currentTestCase;;) { + try { MINUTES.sleep(timeoutMinutes); } + catch (InterruptedException unexpected) { break; } + if (lastTestCase == currentTestCase) { + System.err.printf( + "Looks like we're stuck running test: %s%n", + lastTestCase); +// System.err.printf( +// "Looks like we're stuck running test: %s (%d/%d)%n", +// lastTestCase, currentRun, runsPerTest); +// System.err.println("availableProcessors=" + +// Runtime.getRuntime().availableProcessors()); +// System.err.printf("cpu model = %s%n", cpuModel()); + dumpTestThreads(); + // one stack dump is probably enough; more would be spam + break; + } + lastTestCase = currentTestCase; + }}}; + Thread thread = new Thread(checkForWedgedTest, "checkForWedgedTest"); + thread.setDaemon(true); + thread.start(); + } + +// public static String cpuModel() { +// try { +// java.util.regex.Matcher matcher +// = Pattern.compile("model name\\s*: (.*)") +// .matcher(new String( +// java.nio.file.Files.readAllBytes( +// java.nio.file.Paths.get("/proc/cpuinfo")), "UTF-8")); +// matcher.find(); +// return matcher.group(1); +// } catch (Exception ex) { return null; } +// } + + public void runBare() throws Throwable { + currentTestCase = this; + if (methodFilter == null + || methodFilter.matcher(toString()).find()) + super.runBare(); + } + + protected void runTest() throws Throwable { + for (int i = 0; i < runsPerTest; i++) { + // currentRun = i; + if (profileTests) + runTestProfiled(); + else + super.runTest(); + } + } + + protected void runTestProfiled() throws Throwable { + for (int i = 0; i < 2; i++) { + long startTime = System.nanoTime(); + super.runTest(); + long elapsedMillis = millisElapsedSince(startTime); + if (elapsedMillis < profileThreshold) + break; + // Never report first run of any test; treat it as a + // warmup run, notably to trigger all needed classloading, + if (i > 0) + System.out.printf("%n%s: %d%n", toString(), elapsedMillis); + } + } + + static class PithyResultPrinter extends junit.textui.ResultPrinter { + PithyResultPrinter(java.io.PrintStream writer) { super(writer); } + long runTime; + public void startTest(Test test) {} + protected void printHeader(long runTime) { + this.runTime = runTime; // defer printing for later + } + protected void printFooter(TestResult result) { + if (result.wasSuccessful()) { + getWriter().println("OK (" + result.runCount() + " tests)" + + " Time: " + elapsedTimeAsString(runTime)); + } else { + getWriter().println("Time: " + elapsedTimeAsString(runTime)); + super.printFooter(result); + } + } + } + + /** + * Returns a TestRunner that doesn't bother with unnecessary + * fluff, like printing a "." for each test case. + */ + static junit.textui.TestRunner newPithyTestRunner() { + junit.textui.TestRunner runner = new junit.textui.TestRunner(); + runner.setPrinter(new PithyResultPrinter(System.out)); + return runner; + } + + + public static final double JAVA_CLASS_VERSION; + public static final String JAVA_SPECIFICATION_VERSION; + static { + try { + JAVA_CLASS_VERSION = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Double run() { + return Double.valueOf(System.getProperty("java.class.version"));}}); + JAVA_SPECIFICATION_VERSION = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public String run() { + return System.getProperty("java.specification.version");}}); + } catch (Throwable t) { + throw new Error(t); + } + } + + public static boolean atLeastJava6() { return JAVA_CLASS_VERSION >= 50.0; } + public static boolean atLeastJava7() { return JAVA_CLASS_VERSION >= 51.0; } + public static boolean atLeastJava8() { return JAVA_CLASS_VERSION >= 52.0; } + public static boolean atLeastJava9() { return JAVA_CLASS_VERSION >= 53.0; } + public static boolean atLeastJava10() { return JAVA_CLASS_VERSION >= 54.0; } + public static boolean atLeastJava11() { return JAVA_CLASS_VERSION >= 55.0; } + + /** Returns list of junit-style test method names in given class. */ + public static ArrayList testMethodNames(Class testClass) { + Method[] methods = testClass.getDeclaredMethods(); + ArrayList names = new ArrayList<>(methods.length); + for (Method method : methods) { + if (method.getName().startsWith("test") + && Modifier.isPublic(method.getModifiers()) + // method.getParameterCount() requires jdk8+ + && method.getParameterTypes().length == 0) { + names.add(method.getName()); + } + } + return names; + } + + /** + * Returns junit-style testSuite for the given test class, but + * parameterized by passing extra data to each test. + */ + public static Test parameterizedTestSuite + (Class testClass, + Class dataClass, + ExtraData data) { + try { + TestSuite suite = new TestSuite(); + Constructor c = + testClass.getDeclaredConstructor(dataClass, String.class); + for (String methodName : testMethodNames(testClass)) + suite.addTest((Test) c.newInstance(data, methodName)); + return suite; + } catch (ReflectiveOperationException e) { + throw new AssertionError(e); + } + } + + /** + * Returns junit-style testSuite for the jdk8 extension of the + * given test class, but parameterized by passing extra data to + * each test. Uses reflection to allow compilation in jdk7. + */ + public static Test jdk8ParameterizedTestSuite + (Class testClass, + Class dataClass, + ExtraData data) { + if (atLeastJava8()) { + String name = testClass.getName(); + String name8 = name.replaceAll("Test$", "8Test"); + if (name.equals(name8)) throw new AssertionError(name); + try { + return (Test) + Class.forName(name8) + .getMethod("testSuite", dataClass) + .invoke(null, data); + } catch (ReflectiveOperationException e) { + throw new AssertionError(e); + } + } else { + return new TestSuite(); + } + } + + // Delays for timing-dependent tests, in milliseconds. + + public static long SHORT_DELAY_MS; + public static long SMALL_DELAY_MS; + public static long MEDIUM_DELAY_MS; + public static long LONG_DELAY_MS; + + private static final long RANDOM_TIMEOUT; + private static final long RANDOM_EXPIRED_TIMEOUT; + private static final TimeUnit RANDOM_TIMEUNIT; + static { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + long[] timeouts = { Long.MIN_VALUE, -1, 0, 1, Long.MAX_VALUE }; + RANDOM_TIMEOUT = timeouts[rnd.nextInt(timeouts.length)]; + RANDOM_EXPIRED_TIMEOUT = timeouts[rnd.nextInt(3)]; + TimeUnit[] timeUnits = TimeUnit.values(); + RANDOM_TIMEUNIT = timeUnits[rnd.nextInt(timeUnits.length)]; + } + + /** + * Returns a timeout for use when any value at all will do. + */ + static long randomTimeout() { return RANDOM_TIMEOUT; } + + /** + * Returns a timeout that means "no waiting", i.e. not positive. + */ + static long randomExpiredTimeout() { return RANDOM_EXPIRED_TIMEOUT; } + + /** + * Returns a random non-null TimeUnit. + */ + static TimeUnit randomTimeUnit() { return RANDOM_TIMEUNIT; } + + /** + * Returns the shortest timed delay. This can be scaled up for + * slow machines using the jsr166.delay.factor system property, + * or via jtreg's -timeoutFactor: flag. + * http://openjdk.java.net/jtreg/command-help.html + */ + protected long getShortDelay() { + return (long) (50 * delayFactor); + } + + /** + * Sets delays as multiples of SHORT_DELAY. + */ + protected void setDelays() { + SHORT_DELAY_MS = getShortDelay(); + SMALL_DELAY_MS = SHORT_DELAY_MS * 5; + MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10; + LONG_DELAY_MS = SHORT_DELAY_MS * 200; + } + + private static final long TIMEOUT_DELAY_MS + = (long) (12.0 * Math.cbrt(delayFactor)); + + /** + * Returns a timeout in milliseconds to be used in tests that verify + * that operations block or time out. We want this to be longer + * than the OS scheduling quantum, but not too long, so don't scale + * linearly with delayFactor; we use "crazy" cube root instead. + */ + static long timeoutMillis() { + return TIMEOUT_DELAY_MS; + } + + /** + * Returns a new Date instance representing a time at least + * delayMillis milliseconds in the future. + */ + Date delayedDate(long delayMillis) { + // Add 1 because currentTimeMillis is known to round into the past. + return new Date(System.currentTimeMillis() + delayMillis + 1); + } + + /** + * The first exception encountered if any threadAssertXXX method fails. + */ + private final AtomicReference threadFailure + = new AtomicReference<>(null); + + /** + * Records an exception so that it can be rethrown later in the test + * harness thread, triggering a test case failure. Only the first + * failure is recorded; subsequent calls to this method from within + * the same test have no effect. + */ + public void threadRecordFailure(Throwable t) { + System.err.println(t); + dumpTestThreads(); + threadFailure.compareAndSet(null, t); + } + + public void setUp() { + setDelays(); + } + + void tearDownFail(String format, Object... args) { + String msg = toString() + ": " + String.format(format, args); + System.err.println(msg); + dumpTestThreads(); + throw new AssertionError(msg); + } + + /** + * Extra checks that get done for all test cases. + * + * Triggers test case failure if any thread assertions have failed, + * by rethrowing, in the test harness thread, any exception recorded + * earlier by threadRecordFailure. + * + * Triggers test case failure if interrupt status is set in the main thread. + */ + public void tearDown() throws Exception { + Throwable t = threadFailure.getAndSet(null); + if (t != null) { + if (t instanceof Error) + throw (Error) t; + else if (t instanceof RuntimeException) + throw (RuntimeException) t; + else if (t instanceof Exception) + throw (Exception) t; + else + throw new AssertionError(t.toString(), t); + } + + if (Thread.interrupted()) + tearDownFail("interrupt status set in main thread"); + + checkForkJoinPoolThreadLeaks(); + } + + /** + * Finds missing PoolCleaners + */ + void checkForkJoinPoolThreadLeaks() throws InterruptedException { + Thread[] survivors = new Thread[7]; + int count = Thread.enumerate(survivors); + for (int i = 0; i < count; i++) { + Thread thread = survivors[i]; + String name = thread.getName(); + if (name.startsWith("ForkJoinPool-")) { + // give thread some time to terminate + thread.join(LONG_DELAY_MS); + if (thread.isAlive()) + tearDownFail("Found leaked ForkJoinPool thread thread=%s", + thread); + } + } + + if (!ForkJoinPool.commonPool() + .awaitQuiescence(LONG_DELAY_MS, MILLISECONDS)) + tearDownFail("ForkJoin common pool thread stuck"); + } + + /** + * Just like fail(reason), but additionally recording (using + * threadRecordFailure) any AssertionError thrown, so that the + * current testcase will fail. + */ + public void threadFail(String reason) { + try { + fail(reason); + } catch (AssertionError fail) { + threadRecordFailure(fail); + throw fail; + } + } + + /** + * Just like assertTrue(b), but additionally recording (using + * threadRecordFailure) any AssertionError thrown, so that the + * current testcase will fail. + */ + public void threadAssertTrue(boolean b) { + try { + assertTrue(b); + } catch (AssertionError fail) { + threadRecordFailure(fail); + throw fail; + } + } + + /** + * Just like assertFalse(b), but additionally recording (using + * threadRecordFailure) any AssertionError thrown, so that the + * current testcase will fail. + */ + public void threadAssertFalse(boolean b) { + try { + assertFalse(b); + } catch (AssertionError fail) { + threadRecordFailure(fail); + throw fail; + } + } + + /** + * Just like assertNull(x), but additionally recording (using + * threadRecordFailure) any AssertionError thrown, so that the + * current testcase will fail. + */ + public void threadAssertNull(Object x) { + try { + assertNull(x); + } catch (AssertionError fail) { + threadRecordFailure(fail); + throw fail; + } + } + + /** + * Just like assertEquals(x, y), but additionally recording (using + * threadRecordFailure) any AssertionError thrown, so that the + * current testcase will fail. + */ + public void threadAssertEquals(long x, long y) { + try { + assertEquals(x, y); + } catch (AssertionError fail) { + threadRecordFailure(fail); + throw fail; + } + } + + /** + * Just like assertEquals(x, y), but additionally recording (using + * threadRecordFailure) any AssertionError thrown, so that the + * current testcase will fail. + */ + public void threadAssertEquals(Object x, Object y) { + try { + assertEquals(x, y); + } catch (AssertionError fail) { + threadRecordFailure(fail); + throw fail; + } catch (Throwable fail) { + threadUnexpectedException(fail); + } + } + + /** + * Just like assertSame(x, y), but additionally recording (using + * threadRecordFailure) any AssertionError thrown, so that the + * current testcase will fail. + */ + public void threadAssertSame(Object x, Object y) { + try { + assertSame(x, y); + } catch (AssertionError fail) { + threadRecordFailure(fail); + throw fail; + } + } + + /** + * Calls threadFail with message "should throw exception". + */ + public void threadShouldThrow() { + threadFail("should throw exception"); + } + + /** + * Calls threadFail with message "should throw" + exceptionName. + */ + public void threadShouldThrow(String exceptionName) { + threadFail("should throw " + exceptionName); + } + + /** + * Records the given exception using {@link #threadRecordFailure}, + * then rethrows the exception, wrapping it in an AssertionError + * if necessary. + */ + public void threadUnexpectedException(Throwable t) { + threadRecordFailure(t); + t.printStackTrace(); + if (t instanceof RuntimeException) + throw (RuntimeException) t; + else if (t instanceof Error) + throw (Error) t; + else + throw new AssertionError("unexpected exception: " + t, t); + } + + /** + * Delays, via Thread.sleep, for the given millisecond delay, but + * if the sleep is shorter than specified, may re-sleep or yield + * until time elapses. Ensures that the given time, as measured + * by System.nanoTime(), has elapsed. + */ + static void delay(long millis) throws InterruptedException { + long nanos = millis * (1000 * 1000); + final long wakeupTime = System.nanoTime() + nanos; + do { + if (millis > 0L) + Thread.sleep(millis); + else // too short to sleep + Thread.yield(); + nanos = wakeupTime - System.nanoTime(); + millis = nanos / (1000 * 1000); + } while (nanos >= 0L); + } + + /** + * Allows use of try-with-resources with per-test thread pools. + */ + class PoolCleaner implements AutoCloseable { + private final ExecutorService pool; + public PoolCleaner(ExecutorService pool) { this.pool = pool; } + public void close() { joinPool(pool); } + } + + /** + * An extension of PoolCleaner that has an action to release the pool. + */ + class PoolCleanerWithReleaser extends PoolCleaner { + private final Runnable releaser; + public PoolCleanerWithReleaser(ExecutorService pool, Runnable releaser) { + super(pool); + this.releaser = releaser; + } + public void close() { + try { + releaser.run(); + } finally { + super.close(); + } + } + } + + PoolCleaner cleaner(ExecutorService pool) { + return new PoolCleaner(pool); + } + + PoolCleaner cleaner(ExecutorService pool, Runnable releaser) { + return new PoolCleanerWithReleaser(pool, releaser); + } + + PoolCleaner cleaner(ExecutorService pool, CountDownLatch latch) { + return new PoolCleanerWithReleaser(pool, releaser(latch)); + } + + Runnable releaser(final CountDownLatch latch) { + return new Runnable() { public void run() { + do { latch.countDown(); } + while (latch.getCount() > 0); + }}; + } + + PoolCleaner cleaner(ExecutorService pool, AtomicBoolean flag) { + return new PoolCleanerWithReleaser(pool, releaser(flag)); + } + + Runnable releaser(final AtomicBoolean flag) { + return new Runnable() { public void run() { flag.set(true); }}; + } + + /** + * Waits out termination of a thread pool or fails doing so. + */ + void joinPool(ExecutorService pool) { + try { + pool.shutdown(); + if (!pool.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) { + try { + threadFail("ExecutorService " + pool + + " did not terminate in a timely manner"); + } finally { + // last resort, for the benefit of subsequent tests + pool.shutdownNow(); + pool.awaitTermination(MEDIUM_DELAY_MS, MILLISECONDS); + } + } + } catch (SecurityException ok) { + // Allowed in case test doesn't have privs + } catch (InterruptedException fail) { + threadFail("Unexpected InterruptedException"); + } + } + + /** + * Like Runnable, but with the freedom to throw anything. + * junit folks had the same idea: + * http://junit.org/junit5/docs/snapshot/api/org/junit/gen5/api/Executable.html + */ + interface Action { public void run() throws Throwable; } + + /** + * Runs all the given actions in parallel, failing if any fail. + * Useful for running multiple variants of tests that are + * necessarily individually slow because they must block. + */ + void testInParallel(Action ... actions) { + ExecutorService pool = Executors.newCachedThreadPool(); + try (PoolCleaner cleaner = cleaner(pool)) { + ArrayList> futures = new ArrayList<>(actions.length); + for (final Action action : actions) + futures.add(pool.submit(new CheckedRunnable() { + public void realRun() throws Throwable { action.run();}})); + for (Future future : futures) + try { + assertNull(future.get(LONG_DELAY_MS, MILLISECONDS)); + } catch (ExecutionException ex) { + threadUnexpectedException(ex.getCause()); + } catch (Exception ex) { + threadUnexpectedException(ex); + } + } + } + + /** + * A debugging tool to print stack traces of most threads, as jstack does. + * Uninteresting threads are filtered out. + */ + static void dumpTestThreads() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + try { + System.setSecurityManager(null); + } catch (SecurityException giveUp) { + return; + } + } + + ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + System.err.println("------ stacktrace dump start ------"); + for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) { + final String name = info.getThreadName(); + String lockName; + if ("Signal Dispatcher".equals(name)) + continue; + if ("Reference Handler".equals(name) + && (lockName = info.getLockName()) != null + && lockName.startsWith("java.lang.ref.Reference$Lock")) + continue; + if ("Finalizer".equals(name) + && (lockName = info.getLockName()) != null + && lockName.startsWith("java.lang.ref.ReferenceQueue$Lock")) + continue; + if ("checkForWedgedTest".equals(name)) + continue; + System.err.print(info); + } + System.err.println("------ stacktrace dump end ------"); + + if (sm != null) System.setSecurityManager(sm); + } + + /** + * Checks that thread eventually enters the expected blocked thread state. + */ + void assertThreadBlocks(Thread thread, Thread.State expected) { + // always sleep at least 1 ms, with high probability avoiding + // transitory states + for (long retries = LONG_DELAY_MS * 3 / 4; retries-->0; ) { + try { delay(1); } + catch (InterruptedException fail) { + throw new AssertionError("Unexpected InterruptedException", fail); + } + Thread.State s = thread.getState(); + if (s == expected) + return; + else if (s == Thread.State.TERMINATED) + fail("Unexpected thread termination"); + } + fail("timed out waiting for thread to enter thread state " + expected); + } + + /** + * Checks that future.get times out, with the default timeout of + * {@code timeoutMillis()}. + */ + void assertFutureTimesOut(Future future) { + assertFutureTimesOut(future, timeoutMillis()); + } + + /** + * Checks that future.get times out, with the given millisecond timeout. + */ + void assertFutureTimesOut(Future future, long timeoutMillis) { + long startTime = System.nanoTime(); + try { + future.get(timeoutMillis, MILLISECONDS); + shouldThrow(); + } catch (TimeoutException success) { + } catch (Exception fail) { + threadUnexpectedException(fail); + } finally { future.cancel(true); } + assertTrue(millisElapsedSince(startTime) >= timeoutMillis); + } + + /** + * Fails with message "should throw exception". + */ + public void shouldThrow() { + fail("Should throw exception"); + } + + /** + * Fails with message "should throw " + exceptionName. + */ + public void shouldThrow(String exceptionName) { + fail("Should throw " + exceptionName); + } + + /** + * The maximum number of consecutive spurious wakeups we should + * tolerate (from APIs like LockSupport.park) before failing a test. + */ + static final int MAX_SPURIOUS_WAKEUPS = 10; + + /** + * The number of elements to place in collections, arrays, etc. + */ + public static final int SIZE = 20; + + // Some convenient Integer constants + + public static final Integer zero = new Integer(0); + public static final Integer one = new Integer(1); + public static final Integer two = new Integer(2); + public static final Integer three = new Integer(3); + public static final Integer four = new Integer(4); + public static final Integer five = new Integer(5); + public static final Integer six = new Integer(6); + public static final Integer seven = new Integer(7); + public static final Integer eight = new Integer(8); + public static final Integer nine = new Integer(9); + public static final Integer m1 = new Integer(-1); + public static final Integer m2 = new Integer(-2); + public static final Integer m3 = new Integer(-3); + public static final Integer m4 = new Integer(-4); + public static final Integer m5 = new Integer(-5); + public static final Integer m6 = new Integer(-6); + public static final Integer m10 = new Integer(-10); + + /** + * Runs Runnable r with a security policy that permits precisely + * the specified permissions. If there is no current security + * manager, the runnable is run twice, both with and without a + * security manager. We require that any security manager permit + * getPolicy/setPolicy. + */ + public void runWithPermissions(Runnable r, Permission... permissions) { + SecurityManager sm = System.getSecurityManager(); + if (sm == null) { + r.run(); + } + runWithSecurityManagerWithPermissions(r, permissions); + } + + /** + * Runs Runnable r with a security policy that permits precisely + * the specified permissions. If there is no current security + * manager, a temporary one is set for the duration of the + * Runnable. We require that any security manager permit + * getPolicy/setPolicy. + */ + public void runWithSecurityManagerWithPermissions(Runnable r, + Permission... permissions) { + SecurityManager sm = System.getSecurityManager(); + if (sm == null) { + Policy savedPolicy = Policy.getPolicy(); + try { + Policy.setPolicy(permissivePolicy()); + System.setSecurityManager(new SecurityManager()); + runWithSecurityManagerWithPermissions(r, permissions); + } finally { + System.setSecurityManager(null); + Policy.setPolicy(savedPolicy); + } + } else { + Policy savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(permissions); + Policy.setPolicy(policy); + + try { + r.run(); + } finally { + policy.addPermission(new SecurityPermission("setPolicy")); + Policy.setPolicy(savedPolicy); + } + } + } + + /** + * Runs a runnable without any permissions. + */ + public void runWithoutPermissions(Runnable r) { + runWithPermissions(r); + } + + /** + * A security policy where new permissions can be dynamically added + * or all cleared. + */ + public static class AdjustablePolicy extends java.security.Policy { + Permissions perms = new Permissions(); + AdjustablePolicy(Permission... permissions) { + for (Permission permission : permissions) + perms.add(permission); + } + void addPermission(Permission perm) { perms.add(perm); } + void clearPermissions() { perms = new Permissions(); } + public PermissionCollection getPermissions(CodeSource cs) { + return perms; + } + public PermissionCollection getPermissions(ProtectionDomain pd) { + return perms; + } + public boolean implies(ProtectionDomain pd, Permission p) { + return perms.implies(p); + } + public void refresh() {} + public String toString() { + List ps = new ArrayList<>(); + for (Enumeration e = perms.elements(); e.hasMoreElements();) + ps.add(e.nextElement()); + return "AdjustablePolicy with permissions " + ps; + } + } + + /** + * Returns a policy containing all the permissions we ever need. + */ + public static Policy permissivePolicy() { + return new AdjustablePolicy + // Permissions j.u.c. needs directly + (new RuntimePermission("modifyThread"), + new RuntimePermission("getClassLoader"), + new RuntimePermission("setContextClassLoader"), + // Permissions needed to change permissions! + new SecurityPermission("getPolicy"), + new SecurityPermission("setPolicy"), + new RuntimePermission("setSecurityManager"), + // Permissions needed by the junit test harness + new RuntimePermission("accessDeclaredMembers"), + new PropertyPermission("*", "read"), + new java.io.FilePermission("<>", "read")); + } + + /** + * Sleeps until the given time has elapsed. + * Throws AssertionError if interrupted. + */ + static void sleep(long millis) { + try { + delay(millis); + } catch (InterruptedException fail) { + throw new AssertionError("Unexpected InterruptedException", fail); + } + } + + /** + * Spin-waits up to the specified number of milliseconds for the given + * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING. + */ + void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) { + long startTime = 0L; + for (;;) { + Thread.State s = thread.getState(); + if (s == Thread.State.BLOCKED || + s == Thread.State.WAITING || + s == Thread.State.TIMED_WAITING) + return; + else if (s == Thread.State.TERMINATED) + fail("Unexpected thread termination"); + else if (startTime == 0L) + startTime = System.nanoTime(); + else if (millisElapsedSince(startTime) > timeoutMillis) { + threadAssertTrue(thread.isAlive()); + fail("timed out waiting for thread to enter wait state"); + } + Thread.yield(); + } + } + + /** + * Spin-waits up to the specified number of milliseconds for the given + * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING, + * and additionally satisfy the given condition. + */ + void waitForThreadToEnterWaitState( + Thread thread, long timeoutMillis, Callable waitingForGodot) { + long startTime = 0L; + for (;;) { + Thread.State s = thread.getState(); + if (s == Thread.State.BLOCKED || + s == Thread.State.WAITING || + s == Thread.State.TIMED_WAITING) { + try { + if (waitingForGodot.call()) + return; + } catch (Throwable fail) { threadUnexpectedException(fail); } + } + else if (s == Thread.State.TERMINATED) + fail("Unexpected thread termination"); + else if (startTime == 0L) + startTime = System.nanoTime(); + else if (millisElapsedSince(startTime) > timeoutMillis) { + threadAssertTrue(thread.isAlive()); + fail("timed out waiting for thread to enter wait state"); + } + Thread.yield(); + } + } + + /** + * Spin-waits up to LONG_DELAY_MS milliseconds for the given thread to + * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING. + */ + void waitForThreadToEnterWaitState(Thread thread) { + waitForThreadToEnterWaitState(thread, LONG_DELAY_MS); + } + + /** + * Spin-waits up to LONG_DELAY_MS milliseconds for the given thread to + * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING, + * and additionally satisfy the given condition. + */ + void waitForThreadToEnterWaitState( + Thread thread, Callable waitingForGodot) { + waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, waitingForGodot); + } + + /** + * Returns the number of milliseconds since time given by + * startNanoTime, which must have been previously returned from a + * call to {@link System#nanoTime()}. + */ + static long millisElapsedSince(long startNanoTime) { + return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime); + } + +// void assertTerminatesPromptly(long timeoutMillis, Runnable r) { +// long startTime = System.nanoTime(); +// try { +// r.run(); +// } catch (Throwable fail) { threadUnexpectedException(fail); } +// if (millisElapsedSince(startTime) > timeoutMillis/2) +// throw new AssertionError("did not return promptly"); +// } + +// void assertTerminatesPromptly(Runnable r) { +// assertTerminatesPromptly(LONG_DELAY_MS/2, r); +// } + + /** + * Checks that timed f.get() returns the expected value, and does not + * wait for the timeout to elapse before returning. + */ + void checkTimedGet(Future f, T expectedValue, long timeoutMillis) { + long startTime = System.nanoTime(); + try { + assertEquals(expectedValue, f.get(timeoutMillis, MILLISECONDS)); + } catch (Throwable fail) { threadUnexpectedException(fail); } + if (millisElapsedSince(startTime) > timeoutMillis/2) + throw new AssertionError("timed get did not return promptly"); + } + + void checkTimedGet(Future f, T expectedValue) { + checkTimedGet(f, expectedValue, LONG_DELAY_MS); + } + + /** + * Returns a new started daemon Thread running the given runnable. + */ + Thread newStartedThread(Runnable runnable) { + Thread t = new Thread(runnable); + t.setDaemon(true); + t.start(); + return t; + } + + /** + * Waits for the specified time (in milliseconds) for the thread + * to terminate (using {@link Thread#join(long)}), else interrupts + * the thread (in the hope that it may terminate later) and fails. + */ + void awaitTermination(Thread t, long timeoutMillis) { + try { + t.join(timeoutMillis); + } catch (InterruptedException fail) { + threadUnexpectedException(fail); + } finally { + if (t.getState() != Thread.State.TERMINATED) { + t.interrupt(); + threadFail("timed out waiting for thread to terminate"); + } + } + } + + /** + * Waits for LONG_DELAY_MS milliseconds for the thread to + * terminate (using {@link Thread#join(long)}), else interrupts + * the thread (in the hope that it may terminate later) and fails. + */ + void awaitTermination(Thread t) { + awaitTermination(t, LONG_DELAY_MS); + } + + // Some convenient Runnable classes + + public abstract class CheckedRunnable implements Runnable { + protected abstract void realRun() throws Throwable; + + public final void run() { + try { + realRun(); + } catch (Throwable fail) { + threadUnexpectedException(fail); + } + } + } + + public abstract class ThreadShouldThrow extends Thread { + protected abstract void realRun() throws Throwable; + + final Class exceptionClass; + + ThreadShouldThrow(Class exceptionClass) { + this.exceptionClass = exceptionClass; + } + + public final void run() { + try { + realRun(); + threadShouldThrow(exceptionClass.getSimpleName()); + } catch (Throwable t) { + if (! exceptionClass.isInstance(t)) + threadUnexpectedException(t); + } + } + } + + public abstract class CheckedInterruptedRunnable implements Runnable { + protected abstract void realRun() throws Throwable; + + public final void run() { + try { + realRun(); + threadShouldThrow("InterruptedException"); + } catch (InterruptedException success) { + threadAssertFalse(Thread.interrupted()); + } catch (Throwable fail) { + threadUnexpectedException(fail); + } + } + } + + public abstract class CheckedCallable implements Callable { + protected abstract T realCall() throws Throwable; + + public final T call() { + try { + return realCall(); + } catch (Throwable fail) { + threadUnexpectedException(fail); + return null; + } + } + } + + public abstract class CheckedInterruptedCallable + implements Callable { + protected abstract T realCall() throws Throwable; + + public final T call() { + try { + T result = realCall(); + threadShouldThrow("InterruptedException"); + return result; + } catch (InterruptedException success) { + threadAssertFalse(Thread.interrupted()); + } catch (Throwable fail) { + threadUnexpectedException(fail); + } + return null; + } + } + + public static class NoOpRunnable implements Runnable { + public void run() {} + } + + public static class NoOpCallable implements Callable { + public Object call() { return Boolean.TRUE; } + } + + public static final String TEST_STRING = "a test string"; + + public static class StringTask implements Callable { + final String value; + public StringTask() { this(TEST_STRING); } + public StringTask(String value) { this.value = value; } + public String call() { return value; } + } + + public Callable latchAwaitingStringTask(final CountDownLatch latch) { + return new CheckedCallable() { + protected String realCall() { + try { + latch.await(); + } catch (InterruptedException quittingTime) {} + return TEST_STRING; + }}; + } + + public Runnable countDowner(final CountDownLatch latch) { + return new CheckedRunnable() { + public void realRun() throws InterruptedException { + latch.countDown(); + }}; + } + + class LatchAwaiter extends CheckedRunnable { + static final int NEW = 0; + static final int RUNNING = 1; + static final int DONE = 2; + final CountDownLatch latch; + int state = NEW; + LatchAwaiter(CountDownLatch latch) { this.latch = latch; } + public void realRun() throws InterruptedException { + state = 1; + await(latch); + state = 2; + } + } + + public LatchAwaiter awaiter(CountDownLatch latch) { + return new LatchAwaiter(latch); + } + + public void await(CountDownLatch latch, long timeoutMillis) { + try { + if (!latch.await(timeoutMillis, MILLISECONDS)) + fail("timed out waiting for CountDownLatch for " + + (timeoutMillis/1000) + " sec"); + } catch (Throwable fail) { + threadUnexpectedException(fail); + } + } + + public void await(CountDownLatch latch) { + await(latch, LONG_DELAY_MS); + } + + public void await(Semaphore semaphore) { + try { + if (!semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS)) + fail("timed out waiting for Semaphore for " + + (LONG_DELAY_MS/1000) + " sec"); + } catch (Throwable fail) { + threadUnexpectedException(fail); + } + } + + public void await(CyclicBarrier barrier) { + try { + barrier.await(LONG_DELAY_MS, MILLISECONDS); + } catch (Throwable fail) { + threadUnexpectedException(fail); + } + } + +// /** +// * Spin-waits up to LONG_DELAY_MS until flag becomes true. +// */ +// public void await(AtomicBoolean flag) { +// await(flag, LONG_DELAY_MS); +// } + +// /** +// * Spin-waits up to the specified timeout until flag becomes true. +// */ +// public void await(AtomicBoolean flag, long timeoutMillis) { +// long startTime = System.nanoTime(); +// while (!flag.get()) { +// if (millisElapsedSince(startTime) > timeoutMillis) +// throw new AssertionError("timed out"); +// Thread.yield(); +// } +// } + + public static class NPETask implements Callable { + public String call() { throw new NullPointerException(); } + } + + public class SmallPossiblyInterruptedRunnable extends CheckedRunnable { + protected void realRun() { + try { + delay(SMALL_DELAY_MS); + } catch (InterruptedException ok) {} + } + } + + public Runnable possiblyInterruptedRunnable(final long timeoutMillis) { + return new CheckedRunnable() { + protected void realRun() { + try { + delay(timeoutMillis); + } catch (InterruptedException ok) {} + }}; + } + + /** + * For use as ThreadFactory in constructors + */ + public static class SimpleThreadFactory implements ThreadFactory { + public Thread newThread(Runnable r) { + return new Thread(r); + } + } + + public interface TrackedRunnable extends Runnable { + boolean isDone(); + } + + public static class TrackedNoOpRunnable implements Runnable { + public volatile boolean done = false; + public void run() { + done = true; + } + } + + /** + * Analog of CheckedRunnable for RecursiveAction + */ + public abstract class CheckedRecursiveAction extends RecursiveAction { + protected abstract void realCompute() throws Throwable; + + @Override protected final void compute() { + try { + realCompute(); + } catch (Throwable fail) { + threadUnexpectedException(fail); + } + } + } + + /** + * Analog of CheckedCallable for RecursiveTask + */ + public abstract class CheckedRecursiveTask extends RecursiveTask { + protected abstract T realCompute() throws Throwable; + + @Override protected final T compute() { + try { + return realCompute(); + } catch (Throwable fail) { + threadUnexpectedException(fail); + return null; + } + } + } + + /** + * For use as RejectedExecutionHandler in constructors + */ + public static class NoOpREHandler implements RejectedExecutionHandler { + public void rejectedExecution(Runnable r, + ThreadPoolExecutor executor) {} + } + + /** + * A CyclicBarrier that uses timed await and fails with + * AssertionErrors instead of throwing checked exceptions. + */ + public static class CheckedBarrier extends CyclicBarrier { + public CheckedBarrier(int parties) { super(parties); } + + public int await() { + try { + return super.await(2 * LONG_DELAY_MS, MILLISECONDS); + } catch (TimeoutException timedOut) { + throw new AssertionError("timed out"); + } catch (Exception fail) { + throw new AssertionError("Unexpected exception: " + fail, fail); + } + } + } + + void checkEmpty(BlockingQueue q) { + try { + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertNull(q.peek()); + assertNull(q.poll()); + assertNull(q.poll(randomExpiredTimeout(), randomTimeUnit())); + assertEquals(q.toString(), "[]"); + assertTrue(Arrays.equals(q.toArray(), new Object[0])); + assertFalse(q.iterator().hasNext()); + try { + q.element(); + shouldThrow(); + } catch (NoSuchElementException success) {} + try { + q.iterator().next(); + shouldThrow(); + } catch (NoSuchElementException success) {} + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success) {} + } catch (InterruptedException fail) { threadUnexpectedException(fail); } + } + + void assertSerialEquals(Object x, Object y) { + assertTrue(Arrays.equals(serialBytes(x), serialBytes(y))); + } + + void assertNotSerialEquals(Object x, Object y) { + assertFalse(Arrays.equals(serialBytes(x), serialBytes(y))); + } + + byte[] serialBytes(Object o) { + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(o); + oos.flush(); + oos.close(); + return bos.toByteArray(); + } catch (Throwable fail) { + threadUnexpectedException(fail); + return new byte[0]; + } + } + + void assertImmutable(final Object o) { + if (o instanceof Collection) { + assertThrows( + UnsupportedOperationException.class, + new Runnable() { public void run() { + ((Collection) o).add(null);}}); + } + } + + @SuppressWarnings("unchecked") + T serialClone(T o) { + try { + ObjectInputStream ois = new ObjectInputStream + (new ByteArrayInputStream(serialBytes(o))); + T clone = (T) ois.readObject(); + if (o == clone) assertImmutable(o); + assertSame(o.getClass(), clone.getClass()); + return clone; + } catch (Throwable fail) { + threadUnexpectedException(fail); + return null; + } + } + + /** + * A version of serialClone that leaves error handling (for + * e.g. NotSerializableException) up to the caller. + */ + @SuppressWarnings("unchecked") + T serialClonePossiblyFailing(T o) + throws ReflectiveOperationException, java.io.IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(o); + oos.flush(); + oos.close(); + ObjectInputStream ois = new ObjectInputStream + (new ByteArrayInputStream(bos.toByteArray())); + T clone = (T) ois.readObject(); + if (o == clone) assertImmutable(o); + assertSame(o.getClass(), clone.getClass()); + return clone; + } + + /** + * If o implements Cloneable and has a public clone method, + * returns a clone of o, else null. + */ + @SuppressWarnings("unchecked") + T cloneableClone(T o) { + if (!(o instanceof Cloneable)) return null; + final T clone; + try { + clone = (T) o.getClass().getMethod("clone").invoke(o); + } catch (NoSuchMethodException ok) { + return null; + } catch (ReflectiveOperationException unexpected) { + throw new Error(unexpected); + } + assertNotSame(o, clone); // not 100% guaranteed by spec + assertSame(o.getClass(), clone.getClass()); + return clone; + } + + public void assertThrows(Class expectedExceptionClass, + Runnable... throwingActions) { + for (Runnable throwingAction : throwingActions) { + boolean threw = false; + try { throwingAction.run(); } + catch (Throwable t) { + threw = true; + if (!expectedExceptionClass.isInstance(t)) + throw new AssertionError( + "Expected " + expectedExceptionClass.getName() + + ", got " + t.getClass().getName(), + t); + } + if (!threw) + shouldThrow(expectedExceptionClass.getName()); + } + } + + public void assertIteratorExhausted(Iterator it) { + try { + it.next(); + shouldThrow(); + } catch (NoSuchElementException success) {} + assertFalse(it.hasNext()); + } + + public Callable callableThrowing(final Exception ex) { + return new Callable() { public T call() throws Exception { throw ex; }}; + } + + public Runnable runnableThrowing(final RuntimeException ex) { + return new Runnable() { public void run() { throw ex; }}; + } + + /** A reusable thread pool to be shared by tests. */ + static final ExecutorService cachedThreadPool = + new ThreadPoolExecutor(0, Integer.MAX_VALUE, + 1000L, MILLISECONDS, + new SynchronousQueue()); + + static void shuffle(T[] array) { + Collections.shuffle(Arrays.asList(array), ThreadLocalRandom.current()); + } + + /** + * Returns the same String as would be returned by {@link + * Object#toString}, whether or not the given object's class + * overrides toString(). + * + * @see System#identityHashCode + */ + static String identityString(Object x) { + return x.getClass().getName() + + "@" + Integer.toHexString(System.identityHashCode(x)); + } + + // --- Shared assertions for Executor tests --- + + /** + * Returns maximum number of tasks that can be submitted to given + * pool (with bounded queue) before saturation (when submission + * throws RejectedExecutionException). + */ + static final int saturatedSize(ThreadPoolExecutor pool) { + BlockingQueue q = pool.getQueue(); + return pool.getMaximumPoolSize() + q.size() + q.remainingCapacity(); + } + + @SuppressWarnings("FutureReturnValueIgnored") + void assertNullTaskSubmissionThrowsNullPointerException(Executor e) { + try { + e.execute((Runnable) null); + shouldThrow(); + } catch (NullPointerException success) {} + + if (! (e instanceof ExecutorService)) return; + ExecutorService es = (ExecutorService) e; + try { + es.submit((Runnable) null); + shouldThrow(); + } catch (NullPointerException success) {} + try { + es.submit((Runnable) null, Boolean.TRUE); + shouldThrow(); + } catch (NullPointerException success) {} + try { + es.submit((Callable) null); + shouldThrow(); + } catch (NullPointerException success) {} + + if (! (e instanceof ScheduledExecutorService)) return; + ScheduledExecutorService ses = (ScheduledExecutorService) e; + try { + ses.schedule((Runnable) null, + randomTimeout(), randomTimeUnit()); + shouldThrow(); + } catch (NullPointerException success) {} + try { + ses.schedule((Callable) null, + randomTimeout(), randomTimeUnit()); + shouldThrow(); + } catch (NullPointerException success) {} + try { + ses.scheduleAtFixedRate((Runnable) null, + randomTimeout(), LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (NullPointerException success) {} + try { + ses.scheduleWithFixedDelay((Runnable) null, + randomTimeout(), LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (NullPointerException success) {} + } + + void setRejectedExecutionHandler( + ThreadPoolExecutor p, RejectedExecutionHandler handler) { + p.setRejectedExecutionHandler(handler); + assertSame(handler, p.getRejectedExecutionHandler()); + } + + void assertTaskSubmissionsAreRejected(ThreadPoolExecutor p) { + final RejectedExecutionHandler savedHandler = p.getRejectedExecutionHandler(); + final long savedTaskCount = p.getTaskCount(); + final long savedCompletedTaskCount = p.getCompletedTaskCount(); + final int savedQueueSize = p.getQueue().size(); + final boolean stock = (p.getClass().getClassLoader() == null); + + Runnable r = () -> {}; + Callable c = () -> Boolean.TRUE; + + class Recorder implements RejectedExecutionHandler { + public volatile Runnable r = null; + public volatile ThreadPoolExecutor p = null; + public void reset() { r = null; p = null; } + public void rejectedExecution(Runnable r, ThreadPoolExecutor p) { + assertNull(this.r); + assertNull(this.p); + this.r = r; + this.p = p; + } + } + + // check custom handler is invoked exactly once per task + Recorder recorder = new Recorder(); + setRejectedExecutionHandler(p, recorder); + for (int i = 2; i--> 0; ) { + recorder.reset(); + p.execute(r); + if (stock && p.getClass() == ThreadPoolExecutor.class) + assertSame(r, recorder.r); + assertSame(p, recorder.p); + + recorder.reset(); + assertFalse(p.submit(r).isDone()); + if (stock) assertTrue(!((FutureTask) recorder.r).isDone()); + assertSame(p, recorder.p); + + recorder.reset(); + assertFalse(p.submit(r, Boolean.TRUE).isDone()); + if (stock) assertTrue(!((FutureTask) recorder.r).isDone()); + assertSame(p, recorder.p); + + recorder.reset(); + assertFalse(p.submit(c).isDone()); + if (stock) assertTrue(!((FutureTask) recorder.r).isDone()); + assertSame(p, recorder.p); + + if (p instanceof ScheduledExecutorService) { + ScheduledExecutorService s = (ScheduledExecutorService) p; + ScheduledFuture future; + + recorder.reset(); + future = s.schedule(r, randomTimeout(), randomTimeUnit()); + assertFalse(future.isDone()); + if (stock) assertTrue(!((FutureTask) recorder.r).isDone()); + assertSame(p, recorder.p); + + recorder.reset(); + future = s.schedule(c, randomTimeout(), randomTimeUnit()); + assertFalse(future.isDone()); + if (stock) assertTrue(!((FutureTask) recorder.r).isDone()); + assertSame(p, recorder.p); + + recorder.reset(); + future = s.scheduleAtFixedRate(r, randomTimeout(), LONG_DELAY_MS, MILLISECONDS); + assertFalse(future.isDone()); + if (stock) assertTrue(!((FutureTask) recorder.r).isDone()); + assertSame(p, recorder.p); + + recorder.reset(); + future = s.scheduleWithFixedDelay(r, randomTimeout(), LONG_DELAY_MS, MILLISECONDS); + assertFalse(future.isDone()); + if (stock) assertTrue(!((FutureTask) recorder.r).isDone()); + assertSame(p, recorder.p); + } + } + + // Checking our custom handler above should be sufficient, but + // we add some integration tests of standard handlers. + final AtomicReference thread = new AtomicReference<>(); + final Runnable setThread = () -> thread.set(Thread.currentThread()); + + setRejectedExecutionHandler(p, new ThreadPoolExecutor.AbortPolicy()); + try { + p.execute(setThread); + shouldThrow(); + } catch (RejectedExecutionException success) {} + assertNull(thread.get()); + + setRejectedExecutionHandler(p, new ThreadPoolExecutor.DiscardPolicy()); + p.execute(setThread); + assertNull(thread.get()); + + setRejectedExecutionHandler(p, new ThreadPoolExecutor.CallerRunsPolicy()); + p.execute(setThread); + if (p.isShutdown()) + assertNull(thread.get()); + else + assertSame(Thread.currentThread(), thread.get()); + + setRejectedExecutionHandler(p, savedHandler); + + // check that pool was not perturbed by handlers + assertEquals(savedTaskCount, p.getTaskCount()); + assertEquals(savedCompletedTaskCount, p.getCompletedTaskCount()); + assertEquals(savedQueueSize, p.getQueue().size()); + } + + void assertCollectionsEquals(Collection x, Collection y) { + assertEquals(x, y); + assertEquals(y, x); + assertEquals(x.isEmpty(), y.isEmpty()); + assertEquals(x.size(), y.size()); + if (x instanceof List) { + assertEquals(x.toString(), y.toString()); + } + if (x instanceof List || x instanceof Set) { + assertEquals(x.hashCode(), y.hashCode()); + } + if (x instanceof List || x instanceof Deque) { + assertTrue(Arrays.equals(x.toArray(), y.toArray())); + assertTrue(Arrays.equals(x.toArray(new Object[0]), + y.toArray(new Object[0]))); + } + } + + /** + * A weaker form of assertCollectionsEquals which does not insist + * that the two collections satisfy Object#equals(Object), since + * they may use identity semantics as Deques do. + */ + void assertCollectionsEquivalent(Collection x, Collection y) { + if (x instanceof List || x instanceof Set) + assertCollectionsEquals(x, y); + else { + assertEquals(x.isEmpty(), y.isEmpty()); + assertEquals(x.size(), y.size()); + assertEquals(new HashSet(x), new HashSet(y)); + if (x instanceof Deque) { + assertTrue(Arrays.equals(x.toArray(), y.toArray())); + assertTrue(Arrays.equals(x.toArray(new Object[0]), + y.toArray(new Object[0]))); + } + } + } +} diff --git a/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingDeque8Test.java b/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingDeque8Test.java new file mode 100644 index 000000000..61e714d56 --- /dev/null +++ b/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingDeque8Test.java @@ -0,0 +1,43 @@ +package org.mapdb.jsr166Tests;/* + * Written by Doug Lea and Martin Buchholz with assistance from + * members of JCP JSR-166 Expert Group and released to the public + * domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import java.util.concurrent.BlockingDeque; +import java.util.Spliterator; + +public abstract class LinkedBlockingDeque8Test extends JSR166TestCase { + + + protected abstract BlockingDeque newDeque(); + + + /** + * Spliterator.getComparator always throws IllegalStateException + */ + public void testSpliterator_getComparator() { + assertThrows(IllegalStateException.class, + () -> newDeque().spliterator().getComparator()); + } + + /** + * Spliterator characteristics are as advertised + */ + public void testSpliterator_characteristics() { + BlockingDeque q = newDeque(); + Spliterator s = q.spliterator(); + int characteristics = s.characteristics(); + int required = Spliterator.CONCURRENT + | Spliterator.NONNULL + | Spliterator.ORDERED; + assertEquals(required, characteristics & required); + assertTrue(s.hasCharacteristics(required)); + assertEquals(0, characteristics + & (Spliterator.DISTINCT + | Spliterator.IMMUTABLE + | Spliterator.SORTED)); + } + +} diff --git a/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingDequeTest.java b/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingDequeTest.java new file mode 100644 index 000000000..2db401271 --- /dev/null +++ b/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingDequeTest.java @@ -0,0 +1,1845 @@ +package org.mapdb.jsr166Tests;/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Deque; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Queue; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingDeque; + +public abstract class LinkedBlockingDequeTest extends JSR166TestCase { + + + protected abstract BlockingDeque newDeque(); + + + /** + * Returns a new deque of given size containing consecutive + * Integers 0 ... n - 1. + */ + private static LinkedBlockingDeque populatedDeque(int n) { + LinkedBlockingDeque q = + new LinkedBlockingDeque(n); + assertTrue(q.isEmpty()); + for (int i = 0; i < n; i++) + assertTrue(q.offer(new Integer(i))); + assertFalse(q.isEmpty()); + assertEquals(0, q.remainingCapacity()); + assertEquals(n, q.size()); + assertEquals((Integer) 0, q.peekFirst()); + assertEquals((Integer) (n - 1), q.peekLast()); + return q; + } + + /** + * isEmpty is true before add, false after + */ + public void testEmpty() { + BlockingDeque q = newDeque(); + assertTrue(q.isEmpty()); + q.add(new Integer(1)); + assertFalse(q.isEmpty()); + q.add(new Integer(2)); + q.removeFirst(); + q.removeFirst(); + assertTrue(q.isEmpty()); + } + + /** + * size changes when elements added and removed + */ + public void testSize() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE - i, q.size()); + q.removeFirst(); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.size()); + q.add(new Integer(i)); + } + } + + /** + * offerFirst(null) throws NullPointerException + */ + public void testOfferFirstNull() { + BlockingDeque q = newDeque(); + try { + q.offerFirst(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * offerLast(null) throws NullPointerException + */ + public void testOfferLastNull() { + BlockingDeque q = newDeque(); + try { + q.offerLast(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * OfferFirst succeeds + */ + public void testOfferFirst() { + BlockingDeque q = newDeque(); + assertTrue(q.offerFirst(new Integer(0))); + assertTrue(q.offerFirst(new Integer(1))); + } + + /** + * OfferLast succeeds + */ + public void testOfferLast() { + BlockingDeque q = newDeque(); + assertTrue(q.offerLast(new Integer(0))); + assertTrue(q.offerLast(new Integer(1))); + } + + /** + * pollFirst succeeds unless empty + */ + public void testPollFirst() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.pollFirst()); + } + assertNull(q.pollFirst()); + } + + /** + * pollLast succeeds unless empty + */ + public void testPollLast() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = SIZE - 1; i >= 0; --i) { + assertEquals(i, q.pollLast()); + } + assertNull(q.pollLast()); + } + + /** + * peekFirst returns next element, or null if empty + */ + public void testPeekFirst() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.peekFirst()); + assertEquals(i, q.pollFirst()); + assertTrue(q.peekFirst() == null || + !q.peekFirst().equals(i)); + } + assertNull(q.peekFirst()); + } + + /** + * peek returns next element, or null if empty + */ + public void testPeek() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.peek()); + assertEquals(i, q.pollFirst()); + assertTrue(q.peek() == null || + !q.peek().equals(i)); + } + assertNull(q.peek()); + } + + /** + * peekLast returns next element, or null if empty + */ + public void testPeekLast() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = SIZE - 1; i >= 0; --i) { + assertEquals(i, q.peekLast()); + assertEquals(i, q.pollLast()); + assertTrue(q.peekLast() == null || + !q.peekLast().equals(i)); + } + assertNull(q.peekLast()); + } + + /** + * getFirst() returns first element, or throws NSEE if empty + */ + public void testFirstElement() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.getFirst()); + assertEquals(i, q.pollFirst()); + } + try { + q.getFirst(); + shouldThrow(); + } catch (NoSuchElementException success) {} + assertNull(q.peekFirst()); + } + + /** + * getLast() returns last element, or throws NSEE if empty + */ + public void testLastElement() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = SIZE - 1; i >= 0; --i) { + assertEquals(i, q.getLast()); + assertEquals(i, q.pollLast()); + } + try { + q.getLast(); + shouldThrow(); + } catch (NoSuchElementException success) {} + assertNull(q.peekLast()); + } + + /** + * removeFirst() removes first element, or throws NSEE if empty + */ + public void testRemoveFirst() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.removeFirst()); + } + try { + q.removeFirst(); + shouldThrow(); + } catch (NoSuchElementException success) {} + assertNull(q.peekFirst()); + } + + /** + * removeLast() removes last element, or throws NSEE if empty + */ + public void testRemoveLast() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = SIZE - 1; i >= 0; --i) { + assertEquals(i, q.removeLast()); + } + try { + q.removeLast(); + shouldThrow(); + } catch (NoSuchElementException success) {} + assertNull(q.peekLast()); + } + + /** + * remove removes next element, or throws NSEE if empty + */ + public void testRemove() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.remove()); + } + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success) {} + } + + /** + * removeFirstOccurrence(x) removes x and returns true if present + */ + public void testRemoveFirstOccurrence() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 1; i < SIZE; i += 2) { + assertTrue(q.removeFirstOccurrence(new Integer(i))); + } + for (int i = 0; i < SIZE; i += 2) { + assertTrue(q.removeFirstOccurrence(new Integer(i))); + assertFalse(q.removeFirstOccurrence(new Integer(i + 1))); + } + assertTrue(q.isEmpty()); + } + + /** + * removeLastOccurrence(x) removes x and returns true if present + */ + public void testRemoveLastOccurrence() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 1; i < SIZE; i += 2) { + assertTrue(q.removeLastOccurrence(new Integer(i))); + } + for (int i = 0; i < SIZE; i += 2) { + assertTrue(q.removeLastOccurrence(new Integer(i))); + assertFalse(q.removeLastOccurrence(new Integer(i + 1))); + } + assertTrue(q.isEmpty()); + } + + /** + * peekFirst returns element inserted with addFirst + */ + public void testAddFirst() { + BlockingDeque q = populatedDeque(3); + q.pollLast(); + q.addFirst(four); + assertSame(four, q.peekFirst()); + } + + /** + * peekLast returns element inserted with addLast + */ + public void testAddLast() { + BlockingDeque q = populatedDeque(3); + q.pollLast(); + q.addLast(four); + assertSame(four, q.peekLast()); + } + + /** + * A new deque has the indicated capacity, or Integer.MAX_VALUE if + * none given + */ + public void testConstructor1() { + assertEquals(SIZE, new LinkedBlockingDeque(SIZE).remainingCapacity()); + assertEquals(Integer.MAX_VALUE, newDeque().remainingCapacity()); + } + + /** + * Constructor throws IllegalArgumentException if capacity argument nonpositive + */ + public void testConstructor2() { + try { + new LinkedBlockingDeque(0); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } + + /** + * Initializing from null Collection throws NullPointerException + */ + public void testConstructor3() { + try { + new LinkedBlockingDeque(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * Initializing from Collection of null elements throws NullPointerException + */ + public void testConstructor4() { + Collection elements = Arrays.asList(new Integer[SIZE]); + try { + new LinkedBlockingDeque(elements); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * Initializing from Collection with some null elements throws + * NullPointerException + */ + public void testConstructor5() { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE - 1; ++i) + ints[i] = i; + Collection elements = Arrays.asList(ints); + try { + new LinkedBlockingDeque(elements); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * Deque contains all elements of collection used to initialize + */ + public void testConstructor6() { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = i; + BlockingDeque q = new LinkedBlockingDeque(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + + /** + * Deque transitions from empty to full when elements added + */ + public void testEmptyFull() { + BlockingDeque q = new LinkedBlockingDeque(2); + assertTrue(q.isEmpty()); + assertEquals("should have room for 2", 2, q.remainingCapacity()); + q.add(one); + assertFalse(q.isEmpty()); + q.add(two); + assertFalse(q.isEmpty()); + assertEquals(0, q.remainingCapacity()); + assertFalse(q.offer(three)); + } + + /** + * remainingCapacity decreases on add, increases on remove + */ + public void testRemainingCapacity() { + BlockingQueue q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.remainingCapacity()); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertEquals(i, q.remove()); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE - i, q.remainingCapacity()); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertTrue(q.add(i)); + } + } + + /** + * push(null) throws NPE + */ + public void testPushNull() { + BlockingDeque q = new LinkedBlockingDeque(1); + try { + q.push(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * push succeeds if not full; throws IllegalStateException if full + */ + public void testPush() { + BlockingDeque q = new LinkedBlockingDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + Integer x = new Integer(i); + q.push(x); + assertEquals(x, q.peek()); + } + assertEquals(0, q.remainingCapacity()); + try { + q.push(new Integer(SIZE)); + shouldThrow(); + } catch (IllegalStateException success) {} + } + + /** + * peekFirst returns element inserted with push + */ + public void testPushWithPeek() { + BlockingDeque q = populatedDeque(3); + q.pollLast(); + q.push(four); + assertSame(four, q.peekFirst()); + } + + /** + * pop removes next element, or throws NSEE if empty + */ + public void testPop() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.pop()); + } + try { + q.pop(); + shouldThrow(); + } catch (NoSuchElementException success) {} + } + + /** + * Offer succeeds if not full; fails if full + */ + public void testOffer() { + BlockingDeque q = new LinkedBlockingDeque(1); + assertTrue(q.offer(zero)); + assertFalse(q.offer(one)); + } + + /** + * add succeeds if not full; throws IllegalStateException if full + */ + public void testAdd() { + BlockingDeque q = new LinkedBlockingDeque(SIZE); + for (int i = 0; i < SIZE; ++i) + assertTrue(q.add(new Integer(i))); + assertEquals(0, q.remainingCapacity()); + try { + q.add(new Integer(SIZE)); + shouldThrow(); + } catch (IllegalStateException success) {} + } + + /** + * addAll(this) throws IllegalArgumentException + */ + public void testAddAllSelf() { + BlockingDeque q = populatedDeque(SIZE); + try { + q.addAll(q); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } + + /** + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements + */ + public void testAddAll3() { + BlockingDeque q = new LinkedBlockingDeque(SIZE); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE - 1; ++i) + ints[i] = new Integer(i); + Collection elements = Arrays.asList(ints); + try { + q.addAll(elements); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * addAll throws IllegalStateException if not enough room + */ + public void testAddAll4() { + BlockingDeque q = new LinkedBlockingDeque(SIZE - 1); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + Collection elements = Arrays.asList(ints); + try { + q.addAll(elements); + shouldThrow(); + } catch (IllegalStateException success) {} + } + + /** + * Deque contains all elements, in traversal order, of successful addAll + */ + public void testAddAll5() { + Integer[] empty = new Integer[0]; + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + BlockingDeque q = new LinkedBlockingDeque(SIZE); + assertFalse(q.addAll(Arrays.asList(empty))); + assertTrue(q.addAll(Arrays.asList(ints))); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + + /** + * all elements successfully put are contained + */ + public void testPut() throws InterruptedException { + BlockingDeque q = new LinkedBlockingDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + Integer x = new Integer(i); + q.put(x); + assertTrue(q.contains(x)); + } + assertEquals(0, q.remainingCapacity()); + } + + /** + * put blocks interruptibly if full + */ + public void testBlockingPut() throws InterruptedException { + final BlockingDeque q = new LinkedBlockingDeque(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < SIZE; ++i) + q.put(i); + assertEquals(SIZE, q.size()); + assertEquals(0, q.remainingCapacity()); + + Thread.currentThread().interrupt(); + try { + q.put(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.put(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + assertEquals(SIZE, q.size()); + assertEquals(0, q.remainingCapacity()); + } + + /** + * put blocks interruptibly waiting for take when full + */ + public void testPutWithTake() throws InterruptedException { + final int capacity = 2; + final BlockingDeque q = new LinkedBlockingDeque(capacity); + final CountDownLatch pleaseTake = new CountDownLatch(1); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < capacity; i++) + q.put(i); + pleaseTake.countDown(); + q.put(86); + + Thread.currentThread().interrupt(); + try { + q.put(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.put(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseTake); + assertEquals(0, q.remainingCapacity()); + assertEquals(0, q.take()); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + assertEquals(0, q.remainingCapacity()); + } + + /** + * timed offer times out if full and elements not taken + */ + public void testTimedOffer() { + final BlockingDeque q = new LinkedBlockingDeque(2); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + q.put(new Object()); + q.put(new Object()); + long startTime = System.nanoTime(); + assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + + Thread.currentThread().interrupt(); + try { + q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * take retrieves elements in FIFO order + */ + public void testTake() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.take()); + } + } + + /** + * take removes existing elements until empty, then blocks interruptibly + */ + public void testBlockingTake() throws InterruptedException { + final BlockingDeque q = populatedDeque(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < SIZE; i++) assertEquals(i, q.take()); + + Thread.currentThread().interrupt(); + try { + q.take(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.take(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * poll succeeds unless empty + */ + public void testPoll() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.poll()); + } + assertNull(q.poll()); + } + + /** + * timed poll with zero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll0() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.poll(0, MILLISECONDS)); + } + assertNull(q.poll(0, MILLISECONDS)); + } + + /** + * timed poll with nonzero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + long startTime = System.nanoTime(); + assertEquals(i, q.poll(LONG_DELAY_MS, MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + } + long startTime = System.nanoTime(); + assertNull(q.poll(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + checkEmpty(q); + } + + /** + * Interrupted timed poll throws InterruptedException instead of + * returning timeout status + */ + public void testInterruptedTimedPoll() throws InterruptedException { + final BlockingQueue q = populatedDeque(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + long startTime = System.nanoTime(); + for (int i = 0; i < SIZE; i++) + assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); + + Thread.currentThread().interrupt(); + try { + q.poll(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.poll(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + checkEmpty(q); + } + + /** + * putFirst(null) throws NPE + */ + public void testPutFirstNull() throws InterruptedException { + BlockingDeque q = new LinkedBlockingDeque(SIZE); + try { + q.putFirst(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * all elements successfully putFirst are contained + */ + public void testPutFirst() throws InterruptedException { + BlockingDeque q = new LinkedBlockingDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + Integer x = new Integer(i); + q.putFirst(x); + assertTrue(q.contains(x)); + } + assertEquals(0, q.remainingCapacity()); + } + + /** + * putFirst blocks interruptibly if full + */ + public void testBlockingPutFirst() throws InterruptedException { + final BlockingDeque q = new LinkedBlockingDeque(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < SIZE; ++i) + q.putFirst(i); + assertEquals(SIZE, q.size()); + assertEquals(0, q.remainingCapacity()); + + Thread.currentThread().interrupt(); + try { + q.putFirst(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.putFirst(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + assertEquals(SIZE, q.size()); + assertEquals(0, q.remainingCapacity()); + } + + /** + * putFirst blocks interruptibly waiting for take when full + */ + public void testPutFirstWithTake() throws InterruptedException { + final int capacity = 2; + final BlockingDeque q = new LinkedBlockingDeque(capacity); + final CountDownLatch pleaseTake = new CountDownLatch(1); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < capacity; i++) + q.putFirst(i); + pleaseTake.countDown(); + q.putFirst(86); + + pleaseInterrupt.countDown(); + try { + q.putFirst(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseTake); + assertEquals(0, q.remainingCapacity()); + assertEquals(capacity - 1, q.take()); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + assertEquals(0, q.remainingCapacity()); + } + + /** + * timed offerFirst times out if full and elements not taken + */ + public void testTimedOfferFirst() { + final BlockingDeque q = new LinkedBlockingDeque(2); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + q.putFirst(new Object()); + q.putFirst(new Object()); + long startTime = System.nanoTime(); + assertFalse(q.offerFirst(new Object(), timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + + Thread.currentThread().interrupt(); + try { + q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * take retrieves elements in FIFO order + */ + public void testTakeFirst() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.takeFirst()); + } + } + + /** + * takeFirst() blocks interruptibly when empty + */ + public void testTakeFirstFromEmptyBlocksInterruptibly() { + final BlockingDeque q = newDeque(); + final CountDownLatch threadStarted = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + threadStarted.countDown(); + try { + q.takeFirst(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(threadStarted); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * takeFirst() throws InterruptedException immediately if interrupted + * before waiting + */ + public void testTakeFirstFromEmptyAfterInterrupt() { + final BlockingDeque q = newDeque(); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + Thread.currentThread().interrupt(); + try { + q.takeFirst(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + awaitTermination(t); + } + + /** + * takeLast() blocks interruptibly when empty + */ + public void testTakeLastFromEmptyBlocksInterruptibly() { + final BlockingDeque q = newDeque(); + final CountDownLatch threadStarted = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + threadStarted.countDown(); + try { + q.takeLast(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(threadStarted); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * takeLast() throws InterruptedException immediately if interrupted + * before waiting + */ + public void testTakeLastFromEmptyAfterInterrupt() { + final BlockingDeque q = newDeque(); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + Thread.currentThread().interrupt(); + try { + q.takeLast(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + awaitTermination(t); + } + + /** + * takeFirst removes existing elements until empty, then blocks interruptibly + */ + public void testBlockingTakeFirst() throws InterruptedException { + final BlockingDeque q = populatedDeque(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < SIZE; i++) assertEquals(i, q.takeFirst()); + + Thread.currentThread().interrupt(); + try { + q.takeFirst(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.takeFirst(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * timed pollFirst with zero timeout succeeds when non-empty, else times out + */ + public void testTimedPollFirst0() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.pollFirst(0, MILLISECONDS)); + } + assertNull(q.pollFirst(0, MILLISECONDS)); + } + + /** + * timed pollFirst with nonzero timeout succeeds when non-empty, else times out + */ + public void testTimedPollFirst() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + long startTime = System.nanoTime(); + assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + } + long startTime = System.nanoTime(); + assertNull(q.pollFirst(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + checkEmpty(q); + } + + /** + * Interrupted timed pollFirst throws InterruptedException instead of + * returning timeout status + */ + public void testInterruptedTimedPollFirst() throws InterruptedException { + final BlockingDeque q = populatedDeque(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + long startTime = System.nanoTime(); + for (int i = 0; i < SIZE; i++) + assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS)); + + Thread.currentThread().interrupt(); + try { + q.pollFirst(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.pollFirst(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * timed pollFirst before a delayed offerFirst fails; after offerFirst succeeds; + * on interruption throws + */ + public void testTimedPollFirstWithOfferFirst() throws InterruptedException { + final BlockingDeque q = new LinkedBlockingDeque(2); + final CheckedBarrier barrier = new CheckedBarrier(2); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + long startTime = System.nanoTime(); + assertNull(q.pollFirst(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + + barrier.await(); + + assertSame(zero, q.pollFirst(LONG_DELAY_MS, MILLISECONDS)); + + Thread.currentThread().interrupt(); + try { + q.pollFirst(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + + barrier.await(); + try { + q.pollFirst(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + }}); + + barrier.await(); + long startTime = System.nanoTime(); + assertTrue(q.offerFirst(zero, LONG_DELAY_MS, MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + barrier.await(); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * putLast(null) throws NPE + */ + public void testPutLastNull() throws InterruptedException { + BlockingDeque q = new LinkedBlockingDeque(SIZE); + try { + q.putLast(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * all elements successfully putLast are contained + */ + public void testPutLast() throws InterruptedException { + BlockingDeque q = new LinkedBlockingDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + Integer x = new Integer(i); + q.putLast(x); + assertTrue(q.contains(x)); + } + assertEquals(0, q.remainingCapacity()); + } + + /** + * putLast blocks interruptibly if full + */ + public void testBlockingPutLast() throws InterruptedException { + final BlockingDeque q = new LinkedBlockingDeque(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < SIZE; ++i) + q.putLast(i); + assertEquals(SIZE, q.size()); + assertEquals(0, q.remainingCapacity()); + + Thread.currentThread().interrupt(); + try { + q.putLast(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.putLast(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + assertEquals(SIZE, q.size()); + assertEquals(0, q.remainingCapacity()); + } + + /** + * putLast blocks interruptibly waiting for take when full + */ + public void testPutLastWithTake() throws InterruptedException { + final int capacity = 2; + final BlockingDeque q = new LinkedBlockingDeque(capacity); + final CountDownLatch pleaseTake = new CountDownLatch(1); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < capacity; i++) + q.putLast(i); + pleaseTake.countDown(); + q.putLast(86); + + Thread.currentThread().interrupt(); + try { + q.putLast(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.putLast(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseTake); + assertEquals(0, q.remainingCapacity()); + assertEquals(0, q.take()); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + assertEquals(0, q.remainingCapacity()); + } + + /** + * timed offerLast times out if full and elements not taken + */ + public void testTimedOfferLast() { + final BlockingDeque q = new LinkedBlockingDeque(2); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + q.putLast(new Object()); + q.putLast(new Object()); + long startTime = System.nanoTime(); + assertFalse(q.offerLast(new Object(), timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + + Thread.currentThread().interrupt(); + try { + q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + + pleaseInterrupt.countDown(); + try { + q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * takeLast retrieves elements in FIFO order + */ + public void testTakeLast() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE - i - 1, q.takeLast()); + } + } + + /** + * takeLast removes existing elements until empty, then blocks interruptibly + */ + public void testBlockingTakeLast() throws InterruptedException { + final BlockingDeque q = populatedDeque(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < SIZE; i++) + assertEquals(SIZE - i - 1, q.takeLast()); + + Thread.currentThread().interrupt(); + try { + q.takeLast(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.takeLast(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * timed pollLast with zero timeout succeeds when non-empty, else times out + */ + public void testTimedPollLast0() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE - i - 1, q.pollLast(0, MILLISECONDS)); + } + assertNull(q.pollLast(0, MILLISECONDS)); + } + + /** + * timed pollLast with nonzero timeout succeeds when non-empty, else times out + */ + public void testTimedPollLast() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + long startTime = System.nanoTime(); + assertEquals(SIZE - i - 1, q.pollLast(LONG_DELAY_MS, MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + } + long startTime = System.nanoTime(); + assertNull(q.pollLast(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + checkEmpty(q); + } + + /** + * Interrupted timed pollLast throws InterruptedException instead of + * returning timeout status + */ + public void testInterruptedTimedPollLast() throws InterruptedException { + final BlockingDeque q = populatedDeque(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + long startTime = System.nanoTime(); + for (int i = 0; i < SIZE; i++) + assertEquals(SIZE - i - 1, + q.pollLast(LONG_DELAY_MS, MILLISECONDS)); + + Thread.currentThread().interrupt(); + try { + q.pollLast(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.pollLast(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + checkEmpty(q); + } + + /** + * timed poll before a delayed offerLast fails; after offerLast succeeds; + * on interruption throws + */ + public void testTimedPollWithOfferLast() throws InterruptedException { + final BlockingDeque q = new LinkedBlockingDeque(2); + final CheckedBarrier barrier = new CheckedBarrier(2); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + long startTime = System.nanoTime(); + assertNull(q.poll(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + + barrier.await(); + + assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS)); + + Thread.currentThread().interrupt(); + try { + q.poll(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + barrier.await(); + try { + q.poll(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + }}); + + barrier.await(); + long startTime = System.nanoTime(); + assertTrue(q.offerLast(zero, LONG_DELAY_MS, MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + + barrier.await(); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * element returns next element, or throws NSEE if empty + */ + public void testElement() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.element()); + q.poll(); + } + try { + q.element(); + shouldThrow(); + } catch (NoSuchElementException success) {} + } + + /** + * contains(x) reports true when elements added but not yet removed + */ + public void testContains() { + BlockingDeque q = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.contains(new Integer(i))); + q.poll(); + assertFalse(q.contains(new Integer(i))); + } + } + + /** + * clear removes all elements + */ + public void testClear() { + BlockingDeque q = populatedDeque(SIZE); + q.clear(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertEquals(SIZE, q.remainingCapacity()); + q.add(one); + assertFalse(q.isEmpty()); + assertTrue(q.contains(one)); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll(c) is true when c contains a subset of elements + */ + public void testContainsAll() { + BlockingDeque q = populatedDeque(SIZE); + LinkedBlockingDeque p = new LinkedBlockingDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.containsAll(p)); + assertFalse(p.containsAll(q)); + p.add(new Integer(i)); + } + assertTrue(p.containsAll(q)); + } + + /** + * retainAll(c) retains only those elements of c and reports true if changed + */ + public void testRetainAll() { + BlockingDeque q = populatedDeque(SIZE); + LinkedBlockingDeque p = populatedDeque(SIZE); + for (int i = 0; i < SIZE; ++i) { + boolean changed = q.retainAll(p); + if (i == 0) + assertFalse(changed); + else + assertTrue(changed); + + assertTrue(q.containsAll(p)); + assertEquals(SIZE - i, q.size()); + p.remove(); + } + } + + /** + * removeAll(c) removes only those elements of c and reports true if changed + */ + public void testRemoveAll() { + for (int i = 1; i < SIZE; ++i) { + BlockingDeque q = populatedDeque(SIZE); + LinkedBlockingDeque p = populatedDeque(i); + assertTrue(q.removeAll(p)); + assertEquals(SIZE - i, q.size()); + for (int j = 0; j < i; ++j) { + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); + } + } + } + + /** + * toArray contains all elements in FIFO order + */ + public void testToArray() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + Object[] o = q.toArray(); + for (int i = 0; i < o.length; i++) + assertSame(o[i], q.poll()); + } + + /** + * toArray(a) contains all elements in FIFO order + */ + public void testToArray2() { + LinkedBlockingDeque q = populatedDeque(SIZE); + Integer[] ints = new Integer[SIZE]; + Integer[] array = q.toArray(ints); + assertSame(ints, array); + for (int i = 0; i < ints.length; i++) + assertSame(ints[i], q.remove()); + } + + /** + * toArray(incompatible array type) throws ArrayStoreException + */ + public void testToArray1_BadArg() { + BlockingDeque q = populatedDeque(SIZE); + try { + q.toArray(new String[10]); + shouldThrow(); + } catch (ArrayStoreException success) {} + } + + /** + * iterator iterates through all elements + */ + public void testIterator() throws InterruptedException { + BlockingDeque q = populatedDeque(SIZE); + Iterator it = q.iterator(); + int i; + for (i = 0; it.hasNext(); i++) + assertTrue(q.contains(it.next())); + assertEquals(i, SIZE); + assertIteratorExhausted(it); + + it = q.iterator(); + for (i = 0; it.hasNext(); i++) + assertEquals(it.next(), q.take()); + assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + Deque c = newDeque(); + assertIteratorExhausted(c.iterator()); + assertIteratorExhausted(c.descendingIterator()); + } + + /** + * iterator.remove removes current element + */ + public void testIteratorRemove() { + final BlockingDeque q = new LinkedBlockingDeque(3); + q.add(two); + q.add(one); + q.add(three); + + Iterator it = q.iterator(); + it.next(); + it.remove(); + + it = q.iterator(); + assertSame(it.next(), one); + assertSame(it.next(), three); + assertFalse(it.hasNext()); + } + + /** + * iterator ordering is FIFO + */ + public void testIteratorOrdering() { + final BlockingDeque q = new LinkedBlockingDeque(3); + q.add(one); + q.add(two); + q.add(three); + assertEquals(0, q.remainingCapacity()); + int k = 0; + for (Iterator it = q.iterator(); it.hasNext();) { + assertEquals(++k, it.next()); + } + assertEquals(3, k); + } + + /** + * Modifications do not cause iterators to fail + */ + public void testWeaklyConsistentIteration() { + final BlockingDeque q = new LinkedBlockingDeque(3); + q.add(one); + q.add(two); + q.add(three); + for (Iterator it = q.iterator(); it.hasNext();) { + q.remove(); + it.next(); + } + assertEquals(0, q.size()); + } + + /** + * Descending iterator iterates through all elements + */ + public void testDescendingIterator() { + BlockingDeque q = populatedDeque(SIZE); + int i = 0; + Iterator it = q.descendingIterator(); + while (it.hasNext()) { + assertTrue(q.contains(it.next())); + ++i; + } + assertEquals(i, SIZE); + assertFalse(it.hasNext()); + try { + it.next(); + shouldThrow(); + } catch (NoSuchElementException success) {} + } + + /** + * Descending iterator ordering is reverse FIFO + */ + public void testDescendingIteratorOrdering() { + final BlockingDeque q = newDeque(); + for (int iters = 0; iters < 100; ++iters) { + q.add(new Integer(3)); + q.add(new Integer(2)); + q.add(new Integer(1)); + int k = 0; + for (Iterator it = q.descendingIterator(); it.hasNext();) { + assertEquals(++k, it.next()); + } + + assertEquals(3, k); + q.remove(); + q.remove(); + q.remove(); + } + } + + /** + * descendingIterator.remove removes current element + */ + public void testDescendingIteratorRemove() { + final BlockingDeque q = newDeque(); + for (int iters = 0; iters < 100; ++iters) { + q.add(new Integer(3)); + q.add(new Integer(2)); + q.add(new Integer(1)); + Iterator it = q.descendingIterator(); + assertEquals(it.next(), new Integer(1)); + it.remove(); + assertEquals(it.next(), new Integer(2)); + it = q.descendingIterator(); + assertEquals(it.next(), new Integer(2)); + assertEquals(it.next(), new Integer(3)); + it.remove(); + assertFalse(it.hasNext()); + q.remove(); + } + } + + /** + * toString contains toStrings of elements + */ + public void testToString() { + BlockingDeque q = populatedDeque(SIZE); + String s = q.toString(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(s.contains(String.valueOf(i))); + } + } + + /** + * offer transfers elements across Executor tasks + */ + public void testOfferInExecutor() { + final BlockingDeque q = new LinkedBlockingDeque(2); + q.add(one); + q.add(two); + final CheckedBarrier threadsStarted = new CheckedBarrier(2); + final ExecutorService executor = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(executor)) { + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertFalse(q.offer(three)); + threadsStarted.await(); + assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS)); + assertEquals(0, q.remainingCapacity()); + }}); + + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + threadsStarted.await(); + assertSame(one, q.take()); + }}); + } + } + + /** + * timed poll retrieves elements across Executor threads + */ + public void testPollInExecutor() { + final BlockingDeque q = new LinkedBlockingDeque(2); + final CheckedBarrier threadsStarted = new CheckedBarrier(2); + final ExecutorService executor = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(executor)) { + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertNull(q.poll()); + threadsStarted.await(); + assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS)); + checkEmpty(q); + }}); + + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + threadsStarted.await(); + q.put(one); + }}); + } + } + + /** + * A deserialized/reserialized deque has same elements in same order + */ + public void testSerialization() throws Exception { + Queue x = populatedDeque(SIZE); + Queue y = serialClone(x); + + assertNotSame(y, x); + assertEquals(x.size(), y.size()); + assertEquals(x.toString(), y.toString()); + assertTrue(Arrays.equals(x.toArray(), y.toArray())); + while (!x.isEmpty()) { + assertFalse(y.isEmpty()); + assertEquals(x.remove(), y.remove()); + } + assertTrue(y.isEmpty()); + } + + /** + * drainTo(c) empties deque into another collection c + */ + public void testDrainTo() { + BlockingDeque q = populatedDeque(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertEquals(0, q.size()); + assertEquals(SIZE, l.size()); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + q.add(zero); + q.add(one); + assertFalse(q.isEmpty()); + assertTrue(q.contains(zero)); + assertTrue(q.contains(one)); + l.clear(); + q.drainTo(l); + assertEquals(0, q.size()); + assertEquals(2, l.size()); + for (int i = 0; i < 2; ++i) + assertEquals(l.get(i), new Integer(i)); + } + + /** + * drainTo empties full deque, unblocking a waiting put. + */ + public void testDrainToWithActivePut() throws InterruptedException { + final BlockingDeque q = populatedDeque(SIZE); + Thread t = new Thread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + q.put(new Integer(SIZE + 1)); + }}); + + t.start(); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertTrue(l.size() >= SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + t.join(); + assertTrue(q.size() + l.size() >= SIZE); + } + + /** + * drainTo(c, n) empties first min(n, size) elements of queue into c + */ + public void testDrainToN() { + BlockingDeque q = newDeque(); + for (int i = 0; i < SIZE + 2; ++i) { + for (int j = 0; j < SIZE; j++) + assertTrue(q.offer(new Integer(j))); + ArrayList l = new ArrayList(); + q.drainTo(l, i); + int k = (i < SIZE) ? i : SIZE; + assertEquals(k, l.size()); + assertEquals(SIZE - k, q.size()); + for (int j = 0; j < k; ++j) + assertEquals(l.get(j), new Integer(j)); + do {} while (q.poll() != null); + } + } + + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Deque[] qs = { + new LinkedBlockingDeque(), + populatedDeque(2), + }; + + for (Deque q : qs) { + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + assertFalse(q.removeFirstOccurrence(null)); + assertFalse(q.removeLastOccurrence(null)); + } + } + +} diff --git a/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingQueue8Test.java b/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingQueue8Test.java new file mode 100644 index 000000000..7ce2e492d --- /dev/null +++ b/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingQueue8Test.java @@ -0,0 +1,39 @@ +package org.mapdb.jsr166Tests;/* + * Written by Doug Lea and Martin Buchholz with assistance from + * members of JCP JSR-166 Expert Group and released to the public + * domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.Spliterator; + +public class LinkedBlockingQueue8Test extends JSR166TestCase { + + /** + * Spliterator.getComparator always throws IllegalStateException + */ + public void testSpliterator_getComparator() { + assertThrows(IllegalStateException.class, + () -> new LinkedBlockingQueue().spliterator().getComparator()); + } + + /** + * Spliterator characteristics are as advertised + */ + public void testSpliterator_characteristics() { + LinkedBlockingQueue q = new LinkedBlockingQueue(); + Spliterator s = q.spliterator(); + int characteristics = s.characteristics(); + int required = Spliterator.CONCURRENT + | Spliterator.NONNULL + | Spliterator.ORDERED; + assertEquals(required, characteristics & required); + assertTrue(s.hasCharacteristics(required)); + assertEquals(0, characteristics + & (Spliterator.DISTINCT + | Spliterator.IMMUTABLE + | Spliterator.SORTED)); + } + +} diff --git a/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingQueueTest.java b/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingQueueTest.java new file mode 100644 index 000000000..57ec83d56 --- /dev/null +++ b/src/test/java/org/mapdb/jsr166Tests/LinkedBlockingQueueTest.java @@ -0,0 +1,873 @@ +package org.mapdb.jsr166Tests;/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. + */ + +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Queue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; + +public class LinkedBlockingQueueTest extends JSR166TestCase { + + public static class Unbounded extends BlockingQueueTest { + protected BlockingQueue emptyCollection() { + return new LinkedBlockingQueue(); + } + } + + public static class Bounded extends BlockingQueueTest { + protected BlockingQueue emptyCollection() { + return new LinkedBlockingQueue(SIZE); + } + } + + /** + * Returns a new queue of given size containing consecutive + * Integers 0 ... n - 1. + */ + private static LinkedBlockingQueue populatedQueue(int n) { + LinkedBlockingQueue q = new LinkedBlockingQueue<>(n); + assertTrue(q.isEmpty()); + for (int i = 0; i < n; i++) + assertTrue(q.offer(new Integer(i))); + assertFalse(q.isEmpty()); + assertEquals(0, q.remainingCapacity()); + assertEquals(n, q.size()); + assertEquals((Integer) 0, q.peek()); + return q; + } + + /** + * A new queue has the indicated capacity, or Integer.MAX_VALUE if + * none given + */ + public void testConstructor1() { + assertEquals(SIZE, new LinkedBlockingQueue(SIZE).remainingCapacity()); + assertEquals(Integer.MAX_VALUE, new LinkedBlockingQueue().remainingCapacity()); + } + + /** + * Constructor throws IllegalArgumentException if capacity argument nonpositive + */ + public void testConstructor2() { + try { + new LinkedBlockingQueue(0); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } + + /** + * Initializing from null Collection throws NullPointerException + */ + public void testConstructor3() { + try { + new LinkedBlockingQueue(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * Initializing from Collection of null elements throws NullPointerException + */ + public void testConstructor4() { + Collection elements = Arrays.asList(new Integer[SIZE]); + try { + new LinkedBlockingQueue(elements); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * Initializing from Collection with some null elements throws + * NullPointerException + */ + public void testConstructor5() { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE - 1; ++i) + ints[i] = new Integer(i); + Collection elements = Arrays.asList(ints); + try { + new LinkedBlockingQueue(elements); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * Queue contains all elements of collection used to initialize + */ + public void testConstructor6() { + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints)); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + + /** + * Queue transitions from empty to full when elements added + */ + public void testEmptyFull() { + LinkedBlockingQueue q = new LinkedBlockingQueue(2); + assertTrue(q.isEmpty()); + assertEquals("should have room for 2", 2, q.remainingCapacity()); + q.add(one); + assertFalse(q.isEmpty()); + q.add(two); + assertFalse(q.isEmpty()); + assertEquals(0, q.remainingCapacity()); + assertFalse(q.offer(three)); + } + + /** + * remainingCapacity decreases on add, increases on remove + */ + public void testRemainingCapacity() { + BlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.remainingCapacity()); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertEquals(i, q.remove()); + } + for (int i = 0; i < SIZE; ++i) { + assertEquals(SIZE - i, q.remainingCapacity()); + assertEquals(SIZE, q.size() + q.remainingCapacity()); + assertTrue(q.add(i)); + } + } + + /** + * Offer succeeds if not full; fails if full + */ + public void testOffer() { + LinkedBlockingQueue q = new LinkedBlockingQueue(1); + assertTrue(q.offer(zero)); + assertFalse(q.offer(one)); + } + + /** + * add succeeds if not full; throws IllegalStateException if full + */ + public void testAdd() { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) + assertTrue(q.add(new Integer(i))); + assertEquals(0, q.remainingCapacity()); + try { + q.add(new Integer(SIZE)); + shouldThrow(); + } catch (IllegalStateException success) {} + } + + /** + * addAll(this) throws IllegalArgumentException + */ + public void testAddAllSelf() { + LinkedBlockingQueue q = populatedQueue(SIZE); + try { + q.addAll(q); + shouldThrow(); + } catch (IllegalArgumentException success) {} + } + + /** + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements + */ + public void testAddAll3() { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE - 1; ++i) + ints[i] = new Integer(i); + Collection elements = Arrays.asList(ints); + try { + q.addAll(elements); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * addAll throws IllegalStateException if not enough room + */ + public void testAddAll4() { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE - 1); + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + Collection elements = Arrays.asList(ints); + try { + q.addAll(elements); + shouldThrow(); + } catch (IllegalStateException success) {} + } + + /** + * Queue contains all elements, in traversal order, of successful addAll + */ + public void testAddAll5() { + Integer[] empty = new Integer[0]; + Integer[] ints = new Integer[SIZE]; + for (int i = 0; i < SIZE; ++i) + ints[i] = new Integer(i); + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + assertFalse(q.addAll(Arrays.asList(empty))); + assertTrue(q.addAll(Arrays.asList(ints))); + for (int i = 0; i < SIZE; ++i) + assertEquals(ints[i], q.poll()); + } + + /** + * all elements successfully put are contained + */ + public void testPut() throws InterruptedException { + LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + Integer x = new Integer(i); + q.put(x); + assertTrue(q.contains(x)); + } + assertEquals(0, q.remainingCapacity()); + } + + /** + * put blocks interruptibly if full + */ + public void testBlockingPut() throws InterruptedException { + final LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < SIZE; ++i) + q.put(i); + assertEquals(SIZE, q.size()); + assertEquals(0, q.remainingCapacity()); + + Thread.currentThread().interrupt(); + try { + q.put(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.put(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + assertEquals(SIZE, q.size()); + assertEquals(0, q.remainingCapacity()); + } + + /** + * put blocks interruptibly waiting for take when full + */ + public void testPutWithTake() throws InterruptedException { + final int capacity = 2; + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + final CountDownLatch pleaseTake = new CountDownLatch(1); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < capacity; i++) + q.put(i); + pleaseTake.countDown(); + q.put(86); + + Thread.currentThread().interrupt(); + try { + q.put(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.put(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseTake); + assertEquals(0, q.remainingCapacity()); + assertEquals(0, q.take()); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + assertEquals(0, q.remainingCapacity()); + } + + /** + * timed offer times out if full and elements not taken + */ + public void testTimedOffer() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + q.put(new Object()); + q.put(new Object()); + + long startTime = System.nanoTime(); + assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + + Thread.currentThread().interrupt(); + try { + q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * take retrieves elements in FIFO order + */ + public void testTake() throws InterruptedException { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.take()); + } + } + + /** + * Take removes existing elements until empty, then blocks interruptibly + */ + public void testBlockingTake() throws InterruptedException { + final BlockingQueue q = populatedQueue(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + for (int i = 0; i < SIZE; i++) assertEquals(i, q.take()); + + Thread.currentThread().interrupt(); + try { + q.take(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.take(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + } + + /** + * poll succeeds unless empty + */ + public void testPoll() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.poll()); + } + assertNull(q.poll()); + } + + /** + * timed poll with zero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll0() throws InterruptedException { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.poll(0, MILLISECONDS)); + } + assertNull(q.poll(0, MILLISECONDS)); + } + + /** + * timed poll with nonzero timeout succeeds when non-empty, else times out + */ + public void testTimedPoll() throws InterruptedException { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + long startTime = System.nanoTime(); + assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + } + long startTime = System.nanoTime(); + assertNull(q.poll(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + checkEmpty(q); + } + + /** + * Interrupted timed poll throws InterruptedException instead of + * returning timeout status + */ + public void testInterruptedTimedPoll() throws InterruptedException { + final BlockingQueue q = populatedQueue(SIZE); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + long startTime = System.nanoTime(); + for (int i = 0; i < SIZE; i++) + assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); + + Thread.currentThread().interrupt(); + try { + q.poll(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + q.poll(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); + checkEmpty(q); + } + + /** + * peek returns next element, or null if empty + */ + public void testPeek() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.peek()); + assertEquals(i, q.poll()); + assertTrue(q.peek() == null || + !q.peek().equals(i)); + } + assertNull(q.peek()); + } + + /** + * element returns next element, or throws NSEE if empty + */ + public void testElement() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.element()); + assertEquals(i, q.poll()); + } + try { + q.element(); + shouldThrow(); + } catch (NoSuchElementException success) {} + } + + /** + * remove removes next element, or throws NSEE if empty + */ + public void testRemove() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertEquals(i, q.remove()); + } + try { + q.remove(); + shouldThrow(); + } catch (NoSuchElementException success) {} + } + + /** + * An add following remove(x) succeeds + */ + public void testRemoveElementAndAdd() throws InterruptedException { + LinkedBlockingQueue q = new LinkedBlockingQueue(); + assertTrue(q.add(new Integer(1))); + assertTrue(q.add(new Integer(2))); + assertTrue(q.remove(new Integer(1))); + assertTrue(q.remove(new Integer(2))); + assertTrue(q.add(new Integer(3))); + assertNotNull(q.take()); + } + + /** + * contains(x) reports true when elements added but not yet removed + */ + public void testContains() { + LinkedBlockingQueue q = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.contains(new Integer(i))); + q.poll(); + assertFalse(q.contains(new Integer(i))); + } + } + + /** + * clear removes all elements + */ + public void testClear() { + LinkedBlockingQueue q = populatedQueue(SIZE); + q.clear(); + assertTrue(q.isEmpty()); + assertEquals(0, q.size()); + assertEquals(SIZE, q.remainingCapacity()); + q.add(one); + assertFalse(q.isEmpty()); + assertTrue(q.contains(one)); + q.clear(); + assertTrue(q.isEmpty()); + } + + /** + * containsAll(c) is true when c contains a subset of elements + */ + public void testContainsAll() { + LinkedBlockingQueue q = populatedQueue(SIZE); + LinkedBlockingQueue p = new LinkedBlockingQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + assertTrue(q.containsAll(p)); + assertFalse(p.containsAll(q)); + p.add(new Integer(i)); + } + assertTrue(p.containsAll(q)); + } + + /** + * retainAll(c) retains only those elements of c and reports true if changed + */ + public void testRetainAll() { + LinkedBlockingQueue q = populatedQueue(SIZE); + LinkedBlockingQueue p = populatedQueue(SIZE); + for (int i = 0; i < SIZE; ++i) { + boolean changed = q.retainAll(p); + if (i == 0) + assertFalse(changed); + else + assertTrue(changed); + + assertTrue(q.containsAll(p)); + assertEquals(SIZE - i, q.size()); + p.remove(); + } + } + + /** + * removeAll(c) removes only those elements of c and reports true if changed + */ + public void testRemoveAll() { + for (int i = 1; i < SIZE; ++i) { + LinkedBlockingQueue q = populatedQueue(SIZE); + LinkedBlockingQueue p = populatedQueue(i); + assertTrue(q.removeAll(p)); + assertEquals(SIZE - i, q.size()); + for (int j = 0; j < i; ++j) { + Integer x = (Integer)(p.remove()); + assertFalse(q.contains(x)); + } + } + } + + /** + * toArray contains all elements in FIFO order + */ + public void testToArray() { + LinkedBlockingQueue q = populatedQueue(SIZE); + Object[] o = q.toArray(); + for (int i = 0; i < o.length; i++) + assertSame(o[i], q.poll()); + } + + /** + * toArray(a) contains all elements in FIFO order + */ + public void testToArray2() throws InterruptedException { + LinkedBlockingQueue q = populatedQueue(SIZE); + Integer[] ints = new Integer[SIZE]; + Integer[] array = q.toArray(ints); + assertSame(ints, array); + for (int i = 0; i < ints.length; i++) + assertSame(ints[i], q.poll()); + } + + /** + * toArray(incompatible array type) throws ArrayStoreException + */ + public void testToArray1_BadArg() { + LinkedBlockingQueue q = populatedQueue(SIZE); + try { + q.toArray(new String[10]); + shouldThrow(); + } catch (ArrayStoreException success) {} + } + + /** + * iterator iterates through all elements + */ + public void testIterator() throws InterruptedException { + LinkedBlockingQueue q = populatedQueue(SIZE); + Iterator it = q.iterator(); + int i; + for (i = 0; it.hasNext(); i++) + assertTrue(q.contains(it.next())); + assertEquals(i, SIZE); + assertIteratorExhausted(it); + + it = q.iterator(); + for (i = 0; it.hasNext(); i++) + assertEquals(it.next(), q.take()); + assertEquals(i, SIZE); + assertIteratorExhausted(it); + } + + /** + * iterator of empty collection has no elements + */ + public void testEmptyIterator() { + assertIteratorExhausted(new LinkedBlockingQueue().iterator()); + } + + /** + * iterator.remove removes current element + */ + public void testIteratorRemove() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(3); + q.add(two); + q.add(one); + q.add(three); + + Iterator it = q.iterator(); + it.next(); + it.remove(); + + it = q.iterator(); + assertSame(it.next(), one); + assertSame(it.next(), three); + assertFalse(it.hasNext()); + } + + /** + * iterator ordering is FIFO + */ + public void testIteratorOrdering() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(3); + q.add(one); + q.add(two); + q.add(three); + assertEquals(0, q.remainingCapacity()); + int k = 0; + for (Iterator it = q.iterator(); it.hasNext();) { + assertEquals(++k, it.next()); + } + assertEquals(3, k); + } + + /** + * Modifications do not cause iterators to fail + */ + public void testWeaklyConsistentIteration() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(3); + q.add(one); + q.add(two); + q.add(three); + for (Iterator it = q.iterator(); it.hasNext();) { + q.remove(); + it.next(); + } + assertEquals(0, q.size()); + } + + /** + * toString contains toStrings of elements + */ + public void testToString() { + LinkedBlockingQueue q = populatedQueue(SIZE); + String s = q.toString(); + for (int i = 0; i < SIZE; ++i) { + assertTrue(s.contains(String.valueOf(i))); + } + } + + /** + * offer transfers elements across Executor tasks + */ + public void testOfferInExecutor() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + q.add(one); + q.add(two); + final CheckedBarrier threadsStarted = new CheckedBarrier(2); + final ExecutorService executor = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(executor)) { + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertFalse(q.offer(three)); + threadsStarted.await(); + assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS)); + assertEquals(0, q.remainingCapacity()); + }}); + + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + threadsStarted.await(); + assertSame(one, q.take()); + }}); + } + } + + /** + * timed poll retrieves elements across Executor threads + */ + public void testPollInExecutor() { + final LinkedBlockingQueue q = new LinkedBlockingQueue(2); + final CheckedBarrier threadsStarted = new CheckedBarrier(2); + final ExecutorService executor = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(executor)) { + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertNull(q.poll()); + threadsStarted.await(); + assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS)); + checkEmpty(q); + }}); + + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + threadsStarted.await(); + q.put(one); + }}); + } + } + + /** + * A deserialized/reserialized queue has same elements in same order + */ + public void testSerialization() throws Exception { + Queue x = populatedQueue(SIZE); + Queue y = serialClone(x); + + assertNotSame(x, y); + assertEquals(x.size(), y.size()); + assertEquals(x.toString(), y.toString()); + assertTrue(Arrays.equals(x.toArray(), y.toArray())); + while (!x.isEmpty()) { + assertFalse(y.isEmpty()); + assertEquals(x.remove(), y.remove()); + } + assertTrue(y.isEmpty()); + } + + /** + * drainTo(c) empties queue into another collection c + */ + public void testDrainTo() { + LinkedBlockingQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertEquals(0, q.size()); + assertEquals(SIZE, l.size()); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + q.add(zero); + q.add(one); + assertFalse(q.isEmpty()); + assertTrue(q.contains(zero)); + assertTrue(q.contains(one)); + l.clear(); + q.drainTo(l); + assertEquals(0, q.size()); + assertEquals(2, l.size()); + for (int i = 0; i < 2; ++i) + assertEquals(l.get(i), new Integer(i)); + } + + /** + * drainTo empties full queue, unblocking a waiting put. + */ + public void testDrainToWithActivePut() throws InterruptedException { + final LinkedBlockingQueue q = populatedQueue(SIZE); + Thread t = new Thread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + q.put(new Integer(SIZE + 1)); + }}); + + t.start(); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertTrue(l.size() >= SIZE); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), new Integer(i)); + t.join(); + assertTrue(q.size() + l.size() >= SIZE); + } + + /** + * drainTo(c, n) empties first min(n, size) elements of queue into c + */ + public void testDrainToN() { + LinkedBlockingQueue q = new LinkedBlockingQueue(); + for (int i = 0; i < SIZE + 2; ++i) { + for (int j = 0; j < SIZE; j++) + assertTrue(q.offer(new Integer(j))); + ArrayList l = new ArrayList(); + q.drainTo(l, i); + int k = (i < SIZE) ? i : SIZE; + assertEquals(k, l.size()); + assertEquals(SIZE - k, q.size()); + for (int j = 0; j < k; ++j) + assertEquals(l.get(j), new Integer(j)); + do {} while (q.poll() != null); + } + } + + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection[] qs = { + new LinkedBlockingQueue(), + populatedQueue(2), + }; + + for (Collection q : qs) { + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + } + } + +} diff --git a/src/test/java/org/mapdb/BTreeMapTest6.java b/src/test/java/org/mapdb/jsr166Tests/TreeMapTest.java similarity index 71% rename from src/test/java/org/mapdb/BTreeMapTest6.java rename to src/test/java/org/mapdb/jsr166Tests/TreeMapTest.java index 06d7c7f93..fa01a4f17 100644 --- a/src/test/java/org/mapdb/BTreeMapTest6.java +++ b/src/test/java/org/mapdb/jsr166Tests/TreeMapTest.java @@ -1,24 +1,20 @@ -package org.mapdb;/* -/* +package org.mapdb.jsr166Tests;/* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ -import junit.framework.Test; -import junit.framework.TestSuite; +import org.jetbrains.annotations.NotNull; import java.util.*; -import java.util.concurrent.ConcurrentNavigableMap; -@SuppressWarnings({"rawtypes","unchecked"}) -public class BTreeMapTest6 extends JSR166TestCase { +abstract class TreeMapTest extends JSR166TestCase { /** * Returns a new map from Integers 1-5 to Strings "A"-"E". */ - ConcurrentNavigableMap map5() { - ConcurrentNavigableMap map = newEmptyMap(); + protected NavigableMap map5() { + NavigableMap map = emptyMap(); assertTrue(map.isEmpty()); map.put(one, "A"); map.put(five, "E"); @@ -30,41 +26,35 @@ ConcurrentNavigableMap map5() { return map; } - protected BTreeMap newEmptyMap() { - return DBMaker.newMemoryDB().make().createTreeMap("test").make(); - } - - public static class Outside extends BTreeMapTest6{ - @Override protected BTreeMap newEmptyMap() { - return DBMaker.newMemoryDB().make().createTreeMap("test").valuesOutsideNodesEnable().make(); - } + @NotNull + abstract NavigableMap emptyMap(); - } + abstract NavigableMap fromSorted(NavigableMap map); /** * clear removes all pairs */ public void testClear() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); map.clear(); assertEquals(0, map.size()); } -// /** -// * copy constructor creates map equal to source map -// */ -// public void testConstructFromSorted() { -// ConcurrentNavigableMap map = map5(); -// ConcurrentNavigableMap map2 = new ConcurrentSkipListMap(map); -// assertEquals(map, map2); -// } + /** + * copy constructor creates map equal to source map + */ + public void testConstructFromSorted() { + NavigableMap map = map5(); + NavigableMap map2 = fromSorted(map); + assertEquals(map, map2); + } /** * Maps with same contents are equal */ public void testEquals() { - ConcurrentNavigableMap map1 = map5(); - ConcurrentNavigableMap map2 = map5(); + NavigableMap map1 = map5(); + NavigableMap map2 = map5(); assertEquals(map1, map2); assertEquals(map2, map1); map1.clear(); @@ -76,7 +66,7 @@ public void testEquals() { * containsKey returns true for contained key */ public void testContainsKey() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); assertTrue(map.containsKey(one)); assertFalse(map.containsKey(zero)); } @@ -85,7 +75,7 @@ public void testContainsKey() { * containsValue returns true for held values */ public void testContainsValue() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); assertTrue(map.containsValue("A")); assertFalse(map.containsValue("Z")); } @@ -95,9 +85,9 @@ public void testContainsValue() { * or null if not present */ public void testGet() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); assertEquals("A", (String)map.get(one)); - ConcurrentNavigableMap empty = newEmptyMap(); + NavigableMap empty = emptyMap(); assertNull(empty.get(one)); } @@ -105,8 +95,8 @@ public void testGet() { * isEmpty is true of empty map and false for non-empty */ public void testIsEmpty() { - ConcurrentNavigableMap empty = newEmptyMap(); - ConcurrentNavigableMap map = map5(); + NavigableMap empty = emptyMap(); + NavigableMap map = map5(); assertTrue(empty.isEmpty()); assertFalse(map.isEmpty()); } @@ -115,7 +105,7 @@ public void testIsEmpty() { * firstKey returns first key */ public void testFirstKey() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); assertEquals(one, map.firstKey()); } @@ -123,7 +113,7 @@ public void testFirstKey() { * lastKey returns last key */ public void testLastKey() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); assertEquals(five, map.lastKey()); } @@ -131,7 +121,7 @@ public void testLastKey() { * keySet.toArray returns contains all keys */ public void testKeySetToArray() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Set s = map.keySet(); Object[] ar = s.toArray(); assertTrue(s.containsAll(Arrays.asList(ar))); @@ -144,7 +134,7 @@ public void testKeySetToArray() { * descendingkeySet.toArray returns contains all keys */ public void testDescendingKeySetToArray() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Set s = map.descendingKeySet(); Object[] ar = s.toArray(); assertEquals(5, ar.length); @@ -157,7 +147,7 @@ public void testDescendingKeySetToArray() { * keySet returns a Set containing all the keys */ public void testKeySet() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Set s = map.keySet(); assertEquals(5, s.size()); assertTrue(s.contains(one)); @@ -171,7 +161,7 @@ public void testKeySet() { * keySet is ordered */ public void testKeySetOrder() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Set s = map.keySet(); Iterator i = s.iterator(); Integer last = (Integer)i.next(); @@ -190,7 +180,7 @@ public void testKeySetOrder() { * descending iterator of key set is inverse ordered */ public void testKeySetDescendingIteratorOrder() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); NavigableSet s = map.navigableKeySet(); Iterator i = s.descendingIterator(); Integer last = (Integer)i.next(); @@ -209,7 +199,7 @@ public void testKeySetDescendingIteratorOrder() { * descendingKeySet is ordered */ public void testDescendingKeySetOrder() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Set s = map.descendingKeySet(); Iterator i = s.iterator(); Integer last = (Integer)i.next(); @@ -228,7 +218,7 @@ public void testDescendingKeySetOrder() { * descending iterator of descendingKeySet is ordered */ public void testDescendingKeySetDescendingIteratorOrder() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); NavigableSet s = map.descendingKeySet(); Iterator i = s.descendingIterator(); Integer last = (Integer)i.next(); @@ -243,27 +233,11 @@ public void testDescendingKeySetDescendingIteratorOrder() { assertEquals(5, count); } - /** - * Values.toArray contains all values - */ - public void testValuesToArray() { - ConcurrentNavigableMap map = map5(); - Collection v = map.values(); - Object[] ar = v.toArray(); - ArrayList s = new ArrayList(Arrays.asList(ar)); - assertEquals(5, ar.length); - assertTrue(s.contains("A")); - assertTrue(s.contains("B")); - assertTrue(s.contains("C")); - assertTrue(s.contains("D")); - assertTrue(s.contains("E")); - } - /** * values collection contains all values */ public void testValues() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Collection s = map.values(); assertEquals(5, s.size()); assertTrue(s.contains("A")); @@ -277,18 +251,18 @@ public void testValues() { * entrySet contains all pairs */ public void testEntrySet() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Set s = map.entrySet(); assertEquals(5, s.size()); Iterator it = s.iterator(); while (it.hasNext()) { Map.Entry e = (Map.Entry) it.next(); assertTrue( - (e.getKey().equals(one) && e.getValue().equals("A")) || - (e.getKey().equals(two) && e.getValue().equals("B")) || - (e.getKey().equals(three) && e.getValue().equals("C")) || - (e.getKey().equals(four) && e.getValue().equals("D")) || - (e.getKey().equals(five) && e.getValue().equals("E"))); + (e.getKey().equals(one) && e.getValue().equals("A")) || + (e.getKey().equals(two) && e.getValue().equals("B")) || + (e.getKey().equals(three) && e.getValue().equals("C")) || + (e.getKey().equals(four) && e.getValue().equals("D")) || + (e.getKey().equals(five) && e.getValue().equals("E"))); } } @@ -296,18 +270,18 @@ public void testEntrySet() { * descendingEntrySet contains all pairs */ public void testDescendingEntrySet() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Set s = map.descendingMap().entrySet(); assertEquals(5, s.size()); Iterator it = s.iterator(); while (it.hasNext()) { Map.Entry e = (Map.Entry) it.next(); assertTrue( - (e.getKey().equals(one) && e.getValue().equals("A")) || - (e.getKey().equals(two) && e.getValue().equals("B")) || - (e.getKey().equals(three) && e.getValue().equals("C")) || - (e.getKey().equals(four) && e.getValue().equals("D")) || - (e.getKey().equals(five) && e.getValue().equals("E"))); + (e.getKey().equals(one) && e.getValue().equals("A")) || + (e.getKey().equals(two) && e.getValue().equals("B")) || + (e.getKey().equals(three) && e.getValue().equals("C")) || + (e.getKey().equals(four) && e.getValue().equals("D")) || + (e.getKey().equals(five) && e.getValue().equals("E"))); } } @@ -315,7 +289,7 @@ public void testDescendingEntrySet() { * entrySet.toArray contains all entries */ public void testEntrySetToArray() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Set s = map.entrySet(); Object[] ar = s.toArray(); assertEquals(5, ar.length); @@ -329,7 +303,7 @@ public void testEntrySetToArray() { * descendingEntrySet.toArray contains all entries */ public void testDescendingEntrySetToArray() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Set s = map.descendingMap().entrySet(); Object[] ar = s.toArray(); assertEquals(5, ar.length); @@ -343,8 +317,8 @@ public void testDescendingEntrySetToArray() { * putAll adds all key-value pairs from the given map */ public void testPutAll() { - ConcurrentNavigableMap empty = newEmptyMap(); - ConcurrentNavigableMap map = map5(); + NavigableMap empty = emptyMap(); + NavigableMap map = map5(); empty.putAll(map); assertEquals(5, empty.size()); assertTrue(empty.containsKey(one)); @@ -354,91 +328,21 @@ public void testPutAll() { assertTrue(empty.containsKey(five)); } - /** - * putIfAbsent works when the given key is not present - */ - public void testPutIfAbsent() { - ConcurrentNavigableMap map = map5(); - map.putIfAbsent(six, "Z"); - assertTrue(map.containsKey(six)); - } - - /** - * putIfAbsent does not add the pair if the key is already present - */ - public void testPutIfAbsent2() { - ConcurrentNavigableMap map = map5(); - assertEquals("A", map.putIfAbsent(one, "Z")); - } - - /** - * replace fails when the given key is not present - */ - public void testReplace() { - ConcurrentNavigableMap map = map5(); - assertNull(map.replace(six, "Z")); - assertFalse(map.containsKey(six)); - } - - /** - * replace succeeds if the key is already present - */ - public void testReplace2() { - ConcurrentNavigableMap map = map5(); - assertNotNull(map.replace(one, "Z")); - assertEquals("Z", map.get(one)); - } - - /** - * replace value fails when the given key not mapped to expected value - */ - public void testReplaceValue() { - ConcurrentNavigableMap map = map5(); - assertEquals("A", map.get(one)); - assertFalse(map.replace(one, "Z", "Z")); - assertEquals("A", map.get(one)); - } - - /** - * replace value succeeds when the given key mapped to expected value - */ - public void testReplaceValue2() { - ConcurrentNavigableMap map = map5(); - assertEquals("A", map.get(one)); - assertTrue(map.replace(one, "A", "Z")); - assertEquals("Z", map.get(one)); - } - /** * remove removes the correct key-value pair from the map */ public void testRemove() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); map.remove(five); assertEquals(4, map.size()); assertFalse(map.containsKey(five)); } - /** - * remove(key,value) removes only if pair present - */ - public void testRemove2() { - ConcurrentNavigableMap map = map5(); - assertTrue(map.containsKey(five)); - assertEquals("E", map.get(five)); - map.remove(five, "E"); - assertEquals(4, map.size()); - assertFalse(map.containsKey(five)); - map.remove(four, "A"); - assertEquals(4, map.size()); - assertTrue(map.containsKey(four)); - } - /** * lowerEntry returns preceding entry. */ public void testLowerEntry() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Map.Entry e1 = map.lowerEntry(three); assertEquals(two, e1.getKey()); @@ -456,7 +360,7 @@ public void testLowerEntry() { * higherEntry returns next entry. */ public void testHigherEntry() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Map.Entry e1 = map.higherEntry(three); assertEquals(four, e1.getKey()); @@ -474,7 +378,7 @@ public void testHigherEntry() { * floorEntry returns preceding entry. */ public void testFloorEntry() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Map.Entry e1 = map.floorEntry(three); assertEquals(three, e1.getKey()); @@ -492,7 +396,7 @@ public void testFloorEntry() { * ceilingEntry returns next entry. */ public void testCeilingEntry() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Map.Entry e1 = map.ceilingEntry(three); assertEquals(three, e1.getKey()); @@ -506,43 +410,11 @@ public void testCeilingEntry() { assertNull(e4); } - /** - * lowerEntry, higherEntry, ceilingEntry, and floorEntry return - * immutable entries - */ - public void testEntryImmutability() { - ConcurrentNavigableMap map = map5(); - Map.Entry e = map.lowerEntry(three); - assertEquals(two, e.getKey()); - try { - e.setValue("X"); - shouldThrow(); - } catch (UnsupportedOperationException success) {} - e = map.higherEntry(zero); - assertEquals(one, e.getKey()); - try { - e.setValue("X"); - shouldThrow(); - } catch (UnsupportedOperationException success) {} - e = map.floorEntry(one); - assertEquals(one, e.getKey()); - try { - e.setValue("X"); - shouldThrow(); - } catch (UnsupportedOperationException success) {} - e = map.ceilingEntry(five); - assertEquals(five, e.getKey()); - try { - e.setValue("X"); - shouldThrow(); - } catch (UnsupportedOperationException success) {} - } - /** * lowerKey returns preceding element */ public void testLowerKey() { - ConcurrentNavigableMap q= map5(); + NavigableMap q = map5(); Object e1 = q.lowerKey(three); assertEquals(two, e1); @@ -560,7 +432,7 @@ public void testLowerKey() { * higherKey returns next element */ public void testHigherKey() { - ConcurrentNavigableMap q= map5(); + NavigableMap q = map5(); Object e1 = q.higherKey(three); assertEquals(four, e1); @@ -578,7 +450,7 @@ public void testHigherKey() { * floorKey returns preceding element */ public void testFloorKey() { - ConcurrentNavigableMap q= map5(); + NavigableMap q = map5(); Object e1 = q.floorKey(three); assertEquals(three, e1); @@ -596,7 +468,7 @@ public void testFloorKey() { * ceilingKey returns next element */ public void testCeilingKey() { - ConcurrentNavigableMap q= map5(); + NavigableMap q = map5(); Object e1 = q.ceilingKey(three); assertEquals(three, e1); @@ -614,7 +486,7 @@ public void testCeilingKey() { * pollFirstEntry returns entries in order */ public void testPollFirstEntry() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Map.Entry e = map.pollFirstEntry(); assertEquals(one, e.getKey()); assertEquals("A", e.getValue()); @@ -641,7 +513,7 @@ public void testPollFirstEntry() { * pollLastEntry returns entries in order */ public void testPollLastEntry() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); Map.Entry e = map.pollLastEntry(); assertEquals(five, e.getKey()); assertEquals("E", e.getValue()); @@ -668,8 +540,8 @@ public void testPollLastEntry() { * size returns the correct values */ public void testSize() { - ConcurrentNavigableMap map = map5(); - ConcurrentNavigableMap empty = newEmptyMap(); + NavigableMap map = map5(); + NavigableMap empty = emptyMap(); assertEquals(0, empty.size()); assertEquals(5, map.size()); } @@ -678,7 +550,7 @@ public void testSize() { * toString contains toString of elements */ public void testToString() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); String s = map.toString(); for (int i = 1; i <= 5; ++i) { assertTrue(s.contains(String.valueOf(i))); @@ -691,8 +563,8 @@ public void testToString() { * get(null) of nonempty map throws NPE */ public void testGet_NullPointerException() { + NavigableMap c = map5(); try { - ConcurrentNavigableMap c = map5(); c.get(null); shouldThrow(); } catch (NullPointerException success) {} @@ -702,120 +574,44 @@ public void testGet_NullPointerException() { * containsKey(null) of nonempty map throws NPE */ public void testContainsKey_NullPointerException() { + NavigableMap c = map5(); try { - ConcurrentNavigableMap c = map5(); c.containsKey(null); shouldThrow(); } catch (NullPointerException success) {} } /** - * containsValue(null) throws NPE - */ - public void testContainsValue_NullPointerException() { - try { - ConcurrentNavigableMap c = newEmptyMap(); - c.containsValue(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * put(null,x) throws NPE - */ - public void testPut1_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.put(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * putIfAbsent(null, x) throws NPE - */ - public void testPutIfAbsent1_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.putIfAbsent(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * replace(null, x) throws NPE - */ - public void testReplace_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.replace(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * replace(null, x, y) throws NPE - */ - public void testReplaceValue_NullPointerException() { - try { - ConcurrentNavigableMap c = map5(); - c.replace(null, one, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * remove(null) throws NPE + * remove(null) throws NPE for nonempty map */ public void testRemove1_NullPointerException() { + NavigableMap c = emptyMap(); + c.put("sadsdf", "asdads"); try { - ConcurrentNavigableMap c = newEmptyMap(); - c.put("sadsdf", "asdads"); c.remove(null); shouldThrow(); } catch (NullPointerException success) {} } /** - * remove(null, x) throws NPE + * A deserialized map equals original */ - public void testRemove2_NullPointerException() { - try { - ConcurrentNavigableMap c = newEmptyMap(); - c.put("sadsdf", "asdads"); - c.remove(null, "whatever"); - shouldThrow(); - } catch (NullPointerException success) {} - } + public void testSerialization() throws Exception { + NavigableMap x = map5(); + NavigableMap y = serialClone(x); - /** - * remove(x, null) returns false - */ - public void testRemove3() { - ConcurrentNavigableMap c = newEmptyMap(); - c.put("sadsdf", "asdads"); - assertFalse(c.remove("sadsdf", null)); + assertNotSame(x, y); + assertEquals(x.size(), y.size()); + assertEquals(x.toString(), y.toString()); + assertEquals(x, y); + assertEquals(y, x); } -// /** -// * A deserialized map equals original -// */ -// public void testSerialization() throws Exception { -// NavigableMap x = map5(); -// NavigableMap y = serialClone(x); -// -// assertNotSame(x, y); -// assertEquals(x.size(), y.size()); -// assertEquals(x.toString(), y.toString()); -// assertEquals(x, y); -// assertEquals(y, x); -// } - /** * subMap returns map with keys in requested range */ public void testSubMapContents() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); NavigableMap sm = map.subMap(two, true, four, false); assertEquals(two, sm.firstKey()); assertEquals(three, sm.lastKey()); @@ -853,7 +649,7 @@ public void testSubMapContents() { } public void testSubMapContents2() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); NavigableMap sm = map.subMap(two, true, three, false); assertEquals(1, sm.size()); assertEquals(two, sm.firstKey()); @@ -888,7 +684,7 @@ public void testSubMapContents2() { * headMap returns map with keys in requested range */ public void testHeadMapContents() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); NavigableMap sm = map.headMap(four, false); assertTrue(sm.containsKey(one)); assertTrue(sm.containsKey(two)); @@ -911,10 +707,10 @@ public void testHeadMapContents() { } /** - * tailMap returns map with keys in requested range + * headMap returns map with keys in requested range */ public void testTailMapContents() { - ConcurrentNavigableMap map = map5(); + NavigableMap map = map5(); NavigableMap sm = map.tailMap(two, true); assertFalse(sm.containsKey(one)); assertTrue(sm.containsKey(two)); @@ -971,16 +767,13 @@ public void testTailMapContents() { Random rnd = new Random(666); BitSet bs; - final boolean expensiveTests = true; - /** * Submaps of submaps subdivide correctly */ public void testRecursiveSubMaps() throws Exception { int mapSize = expensiveTests ? 1000 : 100; - //Class cl = ConcurrentSkipListMap.class; - NavigableMap map = // newMap(cl); - newEmptyMap(); + Class cl = TreeMap.class; + NavigableMap map = newMap(cl); bs = new BitSet(mapSize); populate(map, mapSize); @@ -992,12 +785,12 @@ public void testRecursiveSubMaps() throws Exception { check(map.descendingMap(), 0, mapSize - 1, false); bashSubMap(map.subMap(0, true, mapSize, false), - 0, mapSize - 1, true); + 0, mapSize - 1, true); } static NavigableMap newMap(Class cl) throws Exception { - NavigableMap result = - (NavigableMap) cl.newInstance(); + NavigableMap result + = (NavigableMap) cl.newInstance(); assertEquals(0, result.size()); assertFalse(result.keySet().iterator().hasNext()); return result; @@ -1030,7 +823,7 @@ void mutateMap(NavigableMap map, int min, int max) { // Add entries till we're back to original size while (map.size() < size) { int key = min + rnd.nextInt(rangeSize); - assertTrue(key >= min && key<= max); + assertTrue(key >= min && key <= max); put(map, key); } } @@ -1055,7 +848,7 @@ void mutateSubMap(NavigableMap map, int min, int max) { // Add entries till we're back to original size while (map.size() < size) { int key = min - 5 + rnd.nextInt(rangeSize + 10); - if (key >= min && key<= max) { + if (key >= min && key <= max) { put(map, key); } else { try { @@ -1092,36 +885,36 @@ void bashSubMap(NavigableMap map, // headMap - pick direction and endpoint inclusion randomly boolean incl = rnd.nextBoolean(); - NavigableMap hm = map.headMap(midPoint, incl); + NavigableMap hm = map.headMap(midPoint, incl); if (ascending) { if (rnd.nextBoolean()) bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true); else bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1), - false); + false); } else { if (rnd.nextBoolean()) bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false); else bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max, - true); + true); } // tailMap - pick direction and endpoint inclusion randomly incl = rnd.nextBoolean(); - NavigableMap tm = map.tailMap(midPoint,incl); + NavigableMap tm = map.tailMap(midPoint,incl); if (ascending) { if (rnd.nextBoolean()) bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true); else bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max, - false); + false); } else { if (rnd.nextBoolean()) { bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false); } else { bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1), - true); + true); } } @@ -1134,23 +927,23 @@ void bashSubMap(NavigableMap map, boolean lowIncl = rnd.nextBoolean(); boolean highIncl = rnd.nextBoolean(); if (ascending) { - NavigableMap sm = map.subMap( - endpoints[0], lowIncl, endpoints[1], highIncl); + NavigableMap sm = map.subMap( + endpoints[0], lowIncl, endpoints[1], highIncl); if (rnd.nextBoolean()) bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1), - endpoints[1] - (highIncl ? 0 : 1), true); + endpoints[1] - (highIncl ? 0 : 1), true); else bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1), - endpoints[1] - (highIncl ? 0 : 1), false); + endpoints[1] - (highIncl ? 0 : 1), false); } else { - NavigableMap sm = map.subMap( - endpoints[1], highIncl, endpoints[0], lowIncl); + NavigableMap sm = map.subMap( + endpoints[1], highIncl, endpoints[0], lowIncl); if (rnd.nextBoolean()) bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1), - endpoints[1] - (highIncl ? 0 : 1), false); + endpoints[1] - (highIncl ? 0 : 1), false); else bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1), - endpoints[1] - (highIncl ? 0 : 1), true); + endpoints[1] - (highIncl ? 0 : 1), true); } } @@ -1234,7 +1027,7 @@ private int lastAscending() { assertTrue(bs.get(key)); size2++; assertTrue(previousKey < 0 || - (ascending ? key - previousKey > 0 : key - previousKey < 0)); + (ascending ? key - previousKey > 0 : key - previousKey < 0)); previousKey = key; } assertEquals(size2, size); @@ -1276,4 +1069,4 @@ static boolean eq(Integer i, int j) { return i == null ? j == -1 : i == j; } -} \ No newline at end of file +} diff --git a/src/test/java/org/mapdb/kotlin/Issue888_JavaI.java b/src/test/java/org/mapdb/kotlin/Issue888_JavaI.java new file mode 100644 index 000000000..b7304b7e8 --- /dev/null +++ b/src/test/java/org/mapdb/kotlin/Issue888_JavaI.java @@ -0,0 +1,56 @@ +package org.mapdb.kotlin; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public interface Issue888_JavaI { + + default int aa(){ + return 1; + } + + + default int bb(){ + return 1; + } + + class JJ implements Issue888_JavaI { + @Override + public int aa() { + return 2; + } + } + + + + class JK implements Issue888_KotlinI { + @Override + public int aa() { + return 2; + } + + @Test public void test_override(){ + assertEquals(new JJ().aa(), 2); + assertEquals(new JK().aa(), 2); + assertEquals(new KJ().aa(), 2); + assertEquals(new KK().aa(), 2); + } + + + @Test public void test_not_override(){ + assertEquals(new JJ().bb(), 1); + assertEquals(new JK().bb(), 1); + assertEquals(new KJ().bb(), 1); + assertEquals(new KK().bb(), 1); + } + + + //See Issue 888, if this is removed, compilation fails + // for now we define all interfaces in java + @Override + public int bb() { + return 1; + } + } +} diff --git a/src/test/java/org/mapdb/kotlin/Issue888_KotlinI.kt b/src/test/java/org/mapdb/kotlin/Issue888_KotlinI.kt new file mode 100644 index 000000000..4e7c2a28c --- /dev/null +++ b/src/test/java/org/mapdb/kotlin/Issue888_KotlinI.kt @@ -0,0 +1,53 @@ +package org.mapdb.kotlin + +import org.junit.Assert.assertEquals +import org.junit.Test + +interface Issue888_KotlinI{ + + fun aa(): Int { + return 1 + } + + + //@JvmDefault + fun bb(): Int { + return 1 + } + + + + class KJ : Issue888_JavaI { + override fun aa(): Int { + return 2 + } + } + + + class KK : Issue888_KotlinI { + override fun aa(): Int { + return 2 + } + } + + + class Test2(){ + @Test + fun test_override(){ + assertEquals(Issue888_JavaI.JJ().aa().toLong(), 2) + assertEquals(Issue888_JavaI.JK().aa().toLong(), 2) + assertEquals(KJ().aa().toLong(), 2) + assertEquals(KK().aa().toLong(), 2) + } + + + @Test + fun test_not_override() { + assertEquals(Issue888_JavaI.JJ().bb(), 1) + assertEquals(Issue888_JavaI.JK().bb().toLong(), 1) + assertEquals(Issue888_KotlinI.KJ().bb(), 1) + assertEquals(Issue888_KotlinI.KK().bb().toLong(), 1) + } + } +} + diff --git a/src/test/java/org/mapdb/kotlin/Issue888_serializer_override.java b/src/test/java/org/mapdb/kotlin/Issue888_serializer_override.java new file mode 100644 index 000000000..c340c99c5 --- /dev/null +++ b/src/test/java/org/mapdb/kotlin/Issue888_serializer_override.java @@ -0,0 +1,39 @@ +package org.mapdb.kotlin; + +import org.jetbrains.annotations.NotNull; +import org.junit.Test; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataOutput2; +import org.mapdb.ser.Serializer; + +import static org.junit.Assert.assertEquals; + +public class Issue888_serializer_override { + + + static class AlternateHashSer implements Serializer { + @Override + public int hashCode(Integer integer) { + return -integer; + } + + @Override + public void serialize(@NotNull DataOutput2 out, Integer integer) { + + } + + @Override + public Integer deserialize(@NotNull DataInput2 input) { + return null; + } + + @Override + public Class serializedType() { + return Integer.class; + } + } + + @Test public void ser_default_override(){ + assertEquals(-10, new AlternateHashSer().hashCode(10)); + } +} diff --git a/src/test/java/org/mapdb/list/KernelListHarmonyTest.java b/src/test/java/org/mapdb/list/KernelListHarmonyTest.java new file mode 100644 index 000000000..c65f4d307 --- /dev/null +++ b/src/test/java/org/mapdb/list/KernelListHarmonyTest.java @@ -0,0 +1,24 @@ +package org.mapdb.list; + +import harmony.ArrayListTest; +import org.mapdb.ser.Serializers; +import org.mapdb.store.HeapBufStore; +import org.mapdb.store.Store; + +import java.util.List; + + +public class KernelListHarmonyTest extends ArrayListTest { + + @Override + public List newList() { + Store store = new HeapBufStore(); + return (List) KernelList.Maker + .newList(store, Serializers.JAVA) + .entryStore(new HeapBufStore()) + .make(); + } + + + +} diff --git a/src/test/java/org/mapdb/list/MonolithListHarmonyTest.java b/src/test/java/org/mapdb/list/MonolithListHarmonyTest.java new file mode 100644 index 000000000..34b05bdc5 --- /dev/null +++ b/src/test/java/org/mapdb/list/MonolithListHarmonyTest.java @@ -0,0 +1,22 @@ +package org.mapdb.list; + +import harmony.ArrayListTest; +import org.mapdb.ser.Serializers; +import org.mapdb.store.HeapBufStore; +import org.mapdb.store.Store; + +import java.util.List; + + +//TODO this test is slow, move to longtest +public class MonolithListHarmonyTest extends ArrayListTest { + + @Override + public List newList() { + Store store = new HeapBufStore(); + return (List) MonolithList.Maker + .newList(store, Serializers.JAVA) + .make(); + } + +} diff --git a/src/test/java/org/mapdb/AtomicBooleanTest.java b/src/test/java/org/mapdb/record/BooleanRecordTest.java similarity index 82% rename from src/test/java/org/mapdb/AtomicBooleanTest.java rename to src/test/java/org/mapdb/record/BooleanRecordTest.java index 5015c1227..2a5ceea9f 100644 --- a/src/test/java/org/mapdb/AtomicBooleanTest.java +++ b/src/test/java/org/mapdb/record/BooleanRecordTest.java @@ -1,23 +1,24 @@ -package org.mapdb;/* +/* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/licenses/publicdomain - * Other contributors include Andrew Wright, Jeffrey Hayes, - * Pat Fisher, Mike Judd. + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. */ +package org.mapdb.record; import junit.framework.TestCase; -import org.junit.After; +import org.mapdb.db.DB; -public class AtomicBooleanTest extends TestCase{ +public class BooleanRecordTest extends TestCase{ DB db; - Atomic.Boolean ai; + BooleanRecord ai; @Override protected void setUp() throws Exception { - db = DBMaker.newMemoryDB().transactionDisable().make(); - ai= db.createAtomicBoolean("test", true);; + db = DB.Maker.memoryDB().make(); + ai= new BooleanRecord.Maker(db, "test").init(true).make(); } @Override @@ -26,22 +27,22 @@ protected void tearDown() throws Exception { } - /** + /* * constructor initializes to given value */ public void testConstructor() { assertEquals(true,ai.get()); } - /** + /* * default constructed initializes to false */ public void testConstructor2() { - Atomic.Boolean ai = db.getAtomicBoolean("test2"); + BooleanRecord ai = new BooleanRecord.Maker(db, "test2").make(); assertEquals(false,ai.get()); } - /** + /* * get returns the last value set */ public void testGetSet() { @@ -54,7 +55,7 @@ public void testGetSet() { } - /** + /* * compareAndSet succeeds in changing value if equal to expected else fails */ public void testCompareAndSet() { @@ -69,7 +70,7 @@ public void testCompareAndSet() { assertEquals(true,ai.get()); } - /** + /* * compareAndSet in one thread enables another waiting for value * to succeed */ @@ -86,7 +87,7 @@ public void run() { } - /** + /* * getAndSet returns previous value and sets to given value */ public void testGetAndSet() { @@ -95,11 +96,11 @@ public void testGetAndSet() { assertEquals(false,ai.getAndSet(true)); assertEquals(true,ai.get()); } - /** + /* * toString returns current value. */ public void testToString() { - Atomic.Boolean ai = db.getAtomicBoolean( "test2"); + BooleanRecord ai = new BooleanRecord.Maker(db,"test2").make(); assertEquals(ai.toString(), Boolean.toString(false)); ai.set(true); assertEquals(ai.toString(), Boolean.toString(true)); diff --git a/src/test/java/org/mapdb/AtomicIntegerTest.java b/src/test/java/org/mapdb/record/IntRecordTest.java similarity index 92% rename from src/test/java/org/mapdb/AtomicIntegerTest.java rename to src/test/java/org/mapdb/record/IntRecordTest.java index 7dda1fafe..074d9437e 100644 --- a/src/test/java/org/mapdb/AtomicIntegerTest.java +++ b/src/test/java/org/mapdb/record/IntRecordTest.java @@ -1,4 +1,4 @@ -package org.mapdb;/* +package org.mapdb.record;/* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/licenses/publicdomain @@ -7,17 +7,19 @@ */ import junit.framework.TestCase; +import org.mapdb.db.DB; -public class AtomicIntegerTest extends TestCase { + +public class IntRecordTest extends TestCase { DB db; - Atomic.Integer ai; + IntRecord ai; @Override protected void setUp() throws Exception { - db = DBMaker.newMemoryDB().transactionDisable().make(); - ai = db.createAtomicInteger("test", 1); + db = DB.Maker.memoryDB().make(); + ai = new IntRecord.Maker(db,"test").init(1).make(); } @Override @@ -26,22 +28,22 @@ protected void tearDown() throws Exception { } - /** + /* * constructor initializes to given value */ public void testConstructor(){ assertEquals(1,ai.get()); } - /** + /* * default constructed initializes to zero */ public void testConstructor2(){ - Atomic.Integer ai = db.getAtomicInteger("test2"); + IntRecord ai = new IntRecord.Maker(db,"test2").make(); assertEquals(0,ai.get()); } - /** + /* * get returns the last value set */ public void testGetSet(){ @@ -53,7 +55,7 @@ public void testGetSet(){ } - /** + /* * compareAndSet succeeds in changing value if equal to expected else fails */ public void testCompareAndSet(){ @@ -66,7 +68,7 @@ public void testCompareAndSet(){ assertEquals(7,ai.get()); } - /** + /* * compareAndSet in one thread enables another waiting for value * to succeed */ @@ -85,7 +87,7 @@ public void run() { } - /** + /* * getAndSet returns previous value and sets to given value */ public void testGetAndSet(){ @@ -94,7 +96,7 @@ public void testGetAndSet(){ assertEquals(-10,ai.getAndSet(1)); } - /** + /* * getAndAdd returns previous value and adds given value */ public void testGetAndAdd(){ @@ -104,7 +106,7 @@ public void testGetAndAdd(){ assertEquals(-1,ai.get()); } - /** + /* * getAndDecrement returns previous value and decrements */ public void testGetAndDecrement(){ @@ -113,7 +115,7 @@ public void testGetAndDecrement(){ assertEquals(-1,ai.getAndDecrement()); } - /** + /* * getAndIncrement returns previous value and increments */ public void testGetAndIncrement(){ @@ -127,7 +129,7 @@ public void testGetAndIncrement(){ assertEquals(1,ai.get()); } - /** + /* * addAndGet adds given value to current, and returns current value */ public void testAddAndGet(){ @@ -138,7 +140,7 @@ public void testAddAndGet(){ assertEquals(-1,ai.get()); } - /** + /* * decrementAndGet decrements and returns current value */ public void testDecrementAndGet(){ @@ -149,7 +151,7 @@ public void testDecrementAndGet(){ assertEquals(-2,ai.get()); } - /** + /* * incrementAndGet increments and returns current value */ public void testIncrementAndGet(){ @@ -164,7 +166,7 @@ public void testIncrementAndGet(){ } - /** + /* * toString returns current value. */ public void testToString() { @@ -174,7 +176,7 @@ public void testToString() { } } - /** + /* * longValue returns current value. */ public void testLongValue() { @@ -184,7 +186,7 @@ public void testLongValue() { } } - /** + /* * floatValue returns current value. */ public void testFloatValue() { @@ -194,7 +196,7 @@ public void testFloatValue() { } } - /** + /* * doubleValue returns current value. */ public void testDoubleValue() { diff --git a/src/test/java/org/mapdb/AtomicLongTest.java b/src/test/java/org/mapdb/record/LongRecordTest.java similarity index 84% rename from src/test/java/org/mapdb/AtomicLongTest.java rename to src/test/java/org/mapdb/record/LongRecordTest.java index 0152c15b2..cd62ce5f4 100644 --- a/src/test/java/org/mapdb/AtomicLongTest.java +++ b/src/test/java/org/mapdb/record/LongRecordTest.java @@ -1,4 +1,4 @@ -package org.mapdb;/* +package org.mapdb.record;/* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/licenses/publicdomain @@ -7,16 +7,17 @@ */ import junit.framework.TestCase; +import org.mapdb.db.DB; -public class AtomicLongTest extends TestCase { +public class LongRecordTest extends TestCase { DB db; - Atomic.Long ai; + LongRecord ai; @Override protected void setUp() throws Exception { - db = DBMaker.newMemoryDB().transactionDisable().make(); - ai = db.createAtomicLong("test", 1); + db = DB.Maker.memoryDB().make(); + ai = new LongRecord.Maker(db,"test").init(1).make(); } @Override @@ -24,22 +25,22 @@ protected void tearDown() throws Exception { db.close(); } - /** + /* * constructor initializes to given value */ public void testConstructor(){ assertEquals(1,ai.get()); } - /** + /* * default constructed initializes to zero */ public void testConstructor2(){ - Atomic.Long ai = db.getAtomicLong("test2"); + LongRecord ai = new LongRecord.Maker(db,"test2").make(); assertEquals(0,ai.get()); } - /** + /* * get returns the last value set */ public void testGetSet(){ @@ -51,7 +52,7 @@ public void testGetSet(){ } - /** + /* * compareAndSet succeeds in changing value if equal to expected else fails */ public void testCompareAndSet(){ @@ -64,7 +65,7 @@ public void testCompareAndSet(){ assertEquals(7,ai.get()); } - /** + /* * compareAndSet in one thread enables another waiting for value * to succeed */ @@ -83,7 +84,7 @@ public void run() { } - /** + /* * getAndSet returns previous value and sets to given value */ public void testGetAndSet(){ @@ -92,7 +93,7 @@ public void testGetAndSet(){ assertEquals(-10,ai.getAndSet(1)); } - /** + /* * getAndAdd returns previous value and adds given value */ public void testGetAndAdd(){ @@ -102,7 +103,7 @@ public void testGetAndAdd(){ assertEquals(-1,ai.get()); } - /** + /* * getAndDecrement returns previous value and decrements */ public void testGetAndDecrement(){ @@ -111,7 +112,7 @@ public void testGetAndDecrement(){ assertEquals(-1,ai.getAndDecrement()); } - /** + /* * getAndIncrement returns previous value and increments */ public void testGetAndIncrement(){ @@ -125,7 +126,7 @@ public void testGetAndIncrement(){ assertEquals(1,ai.get()); } - /** + /* * addAndGet adds given value to current, and returns current value */ public void testAddAndGet(){ @@ -136,7 +137,7 @@ public void testAddAndGet(){ assertEquals(-1,ai.get()); } - /** + /* * decrementAndGet decrements and returns current value */ public void testDecrementAndGet(){ @@ -147,7 +148,7 @@ public void testDecrementAndGet(){ assertEquals(-2,ai.get()); } - /** + /* * incrementAndGet increments and returns current value */ public void testIncrementAndGet(){ @@ -162,7 +163,7 @@ public void testIncrementAndGet(){ } - /** + /* * toString returns current value. */ public void testToString() { @@ -172,7 +173,7 @@ public void testToString() { } } - /** + /* * longValue returns current value. */ public void testLongValue() { @@ -182,7 +183,7 @@ public void testLongValue() { } } - /** + /* * floatValue returns current value. */ public void testFloatValue() { @@ -192,7 +193,7 @@ public void testFloatValue() { } } - /** + /* * doubleValue returns current value. */ public void testDoubleValue() { @@ -202,21 +203,21 @@ public void testDoubleValue() { } } - - public void testTX(){ - TxMaker txMaker = DBMaker.newMemoryDB().makeTxMaker(); - - DB db = txMaker.makeTx(); - System.out.println(db.getAtomicLong("counter").incrementAndGet()); - db.commit(); - db = txMaker.makeTx(); - System.out.println(db.getAtomicLong("counter").incrementAndGet()); - db.commit(); - db = txMaker.makeTx(); - System.out.println(db.getAtomicLong("counter").incrementAndGet()); - db.commit(); - - } +// TODO this test?? +// public void testTX(){ +// TxMaker txMaker = DBMaker.memoryDB().makeTxMaker(); +// +// DB db = txMaker.makeTx(); +// System.out.println(db.atomicLong("counter").incrementAndGet()); +// db.commit(); +// db = txMaker.makeTx(); +// System.out.println(db.atomicLong("counter").incrementAndGet()); +// db.commit(); +// db = txMaker.makeTx(); +// System.out.println(db.atomicLong("counter").incrementAndGet()); +// db.commit(); +// +// } } diff --git a/src/test/java/org/mapdb/record/StringRecordTest.java b/src/test/java/org/mapdb/record/StringRecordTest.java new file mode 100644 index 000000000..8ea3b7898 --- /dev/null +++ b/src/test/java/org/mapdb/record/StringRecordTest.java @@ -0,0 +1,98 @@ +package org.mapdb.record; + +import junit.framework.TestCase; +import org.mapdb.db.DB; + +public class StringRecordTest extends TestCase { + + DB db; + StringRecord ai; + + + @Override + protected void setUp() throws Exception { + db = DB.Maker.memoryDB().make(); + ai = new StringRecord.Maker(db, "test").init("test").make(); + } + + @Override + protected void tearDown() throws Exception { + db.close(); + } + + + /* + * constructor initializes to given value + */ + public void testConstructor() { + assertEquals("test", ai.get()); + } + + /* + * default constructed initializes to empty string + */ + public void testConstructor2() { + StringRecord ai = new StringRecord.Maker(db, "test2").make(); + assertEquals("", ai.get()); + } + + /* + * get returns the last value set + */ + public void testGetSet() { + assertEquals("test", ai.get()); + ai.set("test2"); + assertEquals("test2", ai.get()); + ai.set("test3"); + assertEquals("test3", ai.get()); + + } + + /* + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet(){ + assertTrue(ai.compareAndSet("test", "test2")); + assertTrue(ai.compareAndSet("test2", "test3")); + assertEquals("test3", ai.get()); + assertFalse(ai.compareAndSet("test2", "test4")); + assertNotSame("test5", ai.get()); + assertTrue(ai.compareAndSet("test3", "test5")); + assertEquals("test5", ai.get()); + } + + /* + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() throws InterruptedException { + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet("test2", "test3")) Thread.yield(); + }}); + + t.start(); + assertTrue(ai.compareAndSet("test", "test2")); + t.join(0); + assertFalse(t.isAlive()); + assertEquals(ai.get(), "test3"); + } + + /* + * getAndSet returns previous value and sets to given value + */ + public void testGetAndSet(){ + assertEquals("test", ai.getAndSet("test2")); + assertEquals("test2", ai.getAndSet("test3")); + assertEquals("test3", ai.getAndSet("test4")); + } + + /* + * toString returns current value. + */ + public void testToString() { + assertEquals(ai.toString(), ai.get()); + assertEquals(ai.toString(), "test"); + } + +} diff --git a/src/test/java/org/mapdb/record/VarRecordTest.java b/src/test/java/org/mapdb/record/VarRecordTest.java new file mode 100644 index 000000000..05f1e40c3 --- /dev/null +++ b/src/test/java/org/mapdb/record/VarRecordTest.java @@ -0,0 +1,108 @@ +package org.mapdb.record; + +import junit.framework.TestCase; +import org.mapdb.db.DB; +import org.mapdb.ser.Serializers; + +public class VarRecordTest extends TestCase { + + DB db; + VarRecord ai; + + + @Override + protected void setUp() throws Exception { + db = DB.Maker.memoryDB().make(); + ai = new VarRecord.Maker(db, "test", Serializers.STRING).init("test").make(); + } + + @Override + protected void tearDown() throws Exception { + db.close(); + } + + + /* + * constructor initializes to given value + */ + public void testConstructor() { + assertEquals("test", ai.get()); + } + + /* + * default constructed initializes to empty string + */ + public void testConstructor2() { + try { + VarRecord ai = new VarRecord.Maker(db, "test2", Serializers.STRING).make(); + fail(); + } catch (NullPointerException e){ + } + } + + public void testConstructor3() { + VarRecord ai = new VarRecord.Maker(db, "test2", Serializers.STRING).init("aa").make(); + assertEquals("aa", ai.get()); + } + + + /* + * get returns the last value set + */ + public void testGetSet() { + assertEquals("test", ai.get()); + ai.set("test2"); + assertEquals("test2", ai.get()); + ai.set("test3"); + assertEquals("test3", ai.get()); + + } + + /* + * compareAndSet succeeds in changing value if equal to expected else fails + */ + public void testCompareAndSet(){ + assertTrue(ai.compareAndSet("test", "test2")); + assertTrue(ai.compareAndSet("test2", "test3")); + assertEquals("test3", ai.get()); + assertFalse(ai.compareAndSet("test2", "test4")); + assertNotSame("test5", ai.get()); + assertTrue(ai.compareAndSet("test3", "test5")); + assertEquals("test5", ai.get()); + } + + /* + * compareAndSet in one thread enables another waiting for value + * to succeed + */ + public void testCompareAndSetInMultipleThreads() throws InterruptedException { + Thread t = new Thread(new Runnable() { + public void run() { + while(!ai.compareAndSet("test2", "test3")) Thread.yield(); + }}); + + t.start(); + assertTrue(ai.compareAndSet("test", "test2")); + t.join(0); + assertFalse(t.isAlive()); + assertEquals(ai.get(), "test3"); + } + + /* + * getAndSet returns previous value and sets to given value + */ + public void testGetAndSet(){ + assertEquals("test", ai.getAndSet("test2")); + assertEquals("test2", ai.getAndSet("test3")); + assertEquals("test3", ai.getAndSet("test4")); + } + + /* + * toString returns current value. + */ + public void testToString() { + assertEquals(ai.toString(), ai.get()); + assertEquals(ai.toString(), "test"); + } + +} diff --git a/src/test/java/org/mapdb/ser/BTreeKeySerializerTest.java b/src/test/java/org/mapdb/ser/BTreeKeySerializerTest.java new file mode 100644 index 000000000..5a673b196 --- /dev/null +++ b/src/test/java/org/mapdb/ser/BTreeKeySerializerTest.java @@ -0,0 +1,314 @@ +/* +package org.mapdb.ser; + +import org.junit.Ignore; +import org.junit.Test;import org.mapdb.*; +import org.mapdb.db.DB; +import org.mapdb.io.DataInput2; +import org.mapdb.io.DataInput2ByteArray; +import org.mapdb.io.DataOutput2; +import org.mapdb.io.DataOutput2ByteArray; + +import java.io.IOException; +import java.util.*; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mapdb.ser.Serializer.*; + +@SuppressWarnings({"rawtypes","unchecked"}) +public class BTreeKeySerializerTest { + + @Test public void testLong(){ + DB db = DB.Maker.memoryDB() + .make(); + Map m = db.treeMap("test", Serializers.LONG, Serializers.LONG) + .make(); + + for(long i = 0; i<1000;i++){ + m.put(i*i,i*i+1); + } + + for(long i = 0; i<1000;i++){ + assertEquals(i * i + 1, m.get(i * i)); + } + } + + + void checkKeyClone(GroupSerializer ser, Object[] keys) throws IOException { + DataOutput2ByteArray out = new DataOutput2ByteArray(); + ser.valueArraySerialize(out,ser.valueArrayFromArray(keys)); + DataInput2ByteArray in = new DataInput2ByteArray(out.copyBytes()); + + Object[] keys2 = ser.valueArrayToArray(ser.valueArrayDeserialize(in,keys.length)); + assertEquals(in.getPos(), out.pos); + + assertArrayEquals(keys,keys2); + } + + @Test public void testLong2() throws IOException { + Object[][] vals = new Object[][]{ + {Long.MIN_VALUE,Long.MAX_VALUE}, + {Long.MIN_VALUE,1L,Long.MAX_VALUE}, + {-1L,0L,1L}, + {-1L,Long.MAX_VALUE} + }; + + for(Object[] v:vals){ + checkKeyClone(Serializers.LONG, v); + } + } + + @Test public void testLong3(){ + final int SIZE = 5; + long[] testData = new long[SIZE]; + + for(int testDataIndex = 0; testDataIndex < SIZE; testDataIndex++){ + testData[testDataIndex] = (long)(testDataIndex + 1); + } + + for(int testDataIndex = 0; testDataIndex < SIZE; testDataIndex++){ + assertEquals("The returned data for the indexed key for GroupSerializer did not match the data for the key.", + (long)Serializers.LONG.valueArrayGet(testData, testDataIndex), testData[testDataIndex]); + } + } + + @Test public void testInt2() throws IOException { + Object[][] vals = new Object[][]{ + {Integer.MIN_VALUE,Integer.MAX_VALUE}, + {Integer.MIN_VALUE,1,Integer.MAX_VALUE}, + {-1,0,1}, + {-1,Integer.MAX_VALUE} + }; + + for(Object[] v:vals){ + checkKeyClone(Serializers.INTEGER, v); + } + } + + @Test public void testInt3(){ + final int TEST_DATA_SIZE = 5; + int[] testData = new int[TEST_DATA_SIZE]; + + for(int i = 0; i < TEST_DATA_SIZE; i++){ + testData[i] = (int)(i + 1); + } + + for(int i = 0; i < TEST_DATA_SIZE; i++){ + assertEquals("The returned data for the indexed key for GroupSerializer did not match the data for the key.", + (long)Serializers.INTEGER.valueArrayGet(testData, i), testData[i]); + } + } + + @Test public void testString(){ + + + DB db = DBMaker.memoryDB() + .make(); + Map m = db.treeMap("test", Serializers.STRING, Serializers.STRING) + .make(); + + + List list = new ArrayList (); + for(long i = 0; i<1000;i++){ + String s = ""+ Math.random()+(i*i*i); + m.put(s,s+"aa"); + } + + for(String s:list){ + assertEquals(s+"aa",m.get(s)); + } + } + + + @Test public void testUUID() throws IOException { + List ids = new ArrayList(); + for(int i=0;i<100;i++) + ids.add(java.util.UUID.randomUUID()); + + long[] vv = (long[]) Serializers.UUID.valueArrayFromArray(ids.toArray()); + + int i=0; + for(java.util.UUID u:ids){ + assertEquals(u.getMostSignificantBits(),vv[i++]); + assertEquals(u.getLeastSignificantBits(),vv[i++]); + } + + //clone + DataOutput2 out = new DataOutput2ByteArray(); + Serializers.UUID.valueArraySerialize(out, vv); + + DataInput2 in = new DataInput2ByteArray(out.copyBytes()); + long[] nn = (long[]) Serializers.UUID.valueArrayDeserialize(in, ids.size()); + + assertArrayEquals(vv, nn); + + //test key addition + java.util.UUID r = java.util.UUID.randomUUID(); + ids.add(10,r); + long[] vv2 = (long[]) Serializers.UUID.valueArrayPut(vv,10,r); + i=0; + for(java.util.UUID u:ids){ + assertEquals(u.getMostSignificantBits(),vv2[i++]); + assertEquals(u.getLeastSignificantBits(),vv2[i++]); + } + + vv2 = (long[]) Serializers.UUID.valueArrayDeleteValue(vv2,10+1); + + assertArrayEquals(vv,vv2); + } + + + + @Test @Ignore + public void string_formats_compatible() throws IOException { + ArrayList keys = new ArrayList(); + for(int i=0;i<1000;i++){ + keys.add("common prefix "+ TT.randomString(10 + new Random().nextInt(100), 0)); + } + + checkStringSerializers(keys); + } + + + @Test @Ignore + public void string_formats_compatible_no_prefix() throws IOException { + ArrayList keys = new ArrayList(); + for(int i=0;i<1000;i++){ + keys.add(TT.randomString(10 + new Random().nextInt(100),0)); + } + + checkStringSerializers(keys); + } + + @Test @Ignore + public void string_formats_compatible_equal_size() throws IOException { + ArrayList keys = new ArrayList(); + for(int i=0;i<1000;i++){ + keys.add("common prefix "+ TT.randomString(10,0)); + } + + checkStringSerializers(keys); + } + + + + public void checkStringSerializers(ArrayList keys) throws IOException { + Collections.sort(keys); + //first check clone on both + checkKeyClone(Serializers.STRING,keys.toArray()); + checkKeyClone(Serializers.STRING_DELTA,keys.toArray()); + checkKeyClone(Serializers.STRING_DELTA2,keys.toArray()); +// TODO compatible format between STRING DELTA SER? +// //now serializer and deserialize with other and compare +// { +// DataOutput2 out = new DataOutput2(); +// Serializer.STRING_DELTA.valueArraySerialize(out, Serializer.STRING_DELTA.valueArrayFromArray(keys.toArray())); +// +// DataInput2.ByteArray in = new DataInput2.ByteArray(out.buf); +// Object[] keys2 = Serializer.STRING_DELTA2.valueArrayToArray(Serializer.STRING_DELTA2.valueArrayDeserialize(in, keys.size())); +// +// assertArrayEquals(keys.toArray(), keys2); +// } +// +// { +// DataOutput2 out = new DataOutput2(); +// Serializer.STRING_DELTA2.valueArraySerialize(out, Serializer.STRING_DELTA2.valueArrayFromArray(keys.toArray())); +// +// DataInput2.ByteArray in = new DataInput2.ByteArray(out.buf); +// Object[] keys2 = Serializer.STRING_DELTA.valueArrayToArray(Serializer.STRING_DELTA.valueArrayDeserialize(in, keys.size())); +// +// assertArrayEquals(keys.toArray(), keys2); +// } + + //convert to byte[] and check with BYTE_ARRAY serializers + for(int i=0;i ser = new ArraySerializer(Serializers.STRING, String.class); + + String[] s2 = ser.clone(s); + assertTrue(Arrays.equals(s,s2)); + } + +} diff --git a/src/test/java/org/mapdb/ser/SerializerTest.kt b/src/test/java/org/mapdb/ser/SerializerTest.kt new file mode 100644 index 000000000..bdbbba041 --- /dev/null +++ b/src/test/java/org/mapdb/ser/SerializerTest.kt @@ -0,0 +1,1005 @@ +package org.mapdb.ser + +import org.junit.Test +import java.io.Serializable +import java.math.BigDecimal +import java.math.BigInteger +import java.util.* +import org.junit.Assert.* +import org.mapdb.* +import org.mapdb.io.DataIO +import org.mapdb.io.DataInput2ByteArray +import org.mapdb.io.DataOutput2 +import org.mapdb.io.DataOutput2ByteArray + +abstract class SerializerTest { + + val random = Random(); + + abstract fun randomValue(): E + + abstract val serializer: Serializer + + val max = 100L + TT.testScale() + + open val repeat = 100 + + val arraySize = 10 + TT.testScale() * 10 + + fun assertSerEquals(v1: Any?, v2: Any?) { + assertTrue(serializer.equals(v1 as E, v2 as E)) + assertEquals(serializer.hashCode(v1, 0), serializer.hashCode(v2, 0)) + } + + + @Test fun cloneEquals(){ + for(i in 0..max){ + val e = randomValue() + val e2 = TT.clone(e,serializer) + assertSerEquals(e, e2) + } + } + + @Test(timeout = 1000L) + fun randomNotEquals(){ + // two random values should not be equal, + // test will eventually timeout if they are always equal + while(serializer.equals(randomValue(), randomValue())){ + + } + } + + @Test(timeout = 1000L) + fun randomNotEqualHashCode(){ + //two random values should not have equal hash code, + // test will eventually timeout if they are always equal + while(serializer.hashCode(randomValue(),0) == serializer.hashCode(randomValue(),0)){ + + } + } + + open @Test fun trusted(){ + assertTrue(serializer.isTrusted || serializer== Serializers.JAVA + /*|| serializer== Serializers.ELSA*/) + } + + @Test fun fixedSize(){ + val size = serializer.fixedSize(); + if(size<0) + return; + for(i in 0..max) { + val e = randomValue() + val out = DataOutput2ByteArray() + serializer.serialize(out, e); + assertEquals(size,out.pos) + } + } + + @Test fun compare() { + for (i in 0..max) { + val v1 = randomValue() + val v2 = randomValue() + serializer.compare(v1, v2) + } + } + +} + + +abstract class GroupSerializerTest:SerializerTest(){ + val serializer2:GroupSerializer + get() = serializer as GroupSerializer + + + + @Test open fun valueArrayBinarySearch(){ + var v = ArrayList() + for (i in 0..max) { + v.add(randomValue()) + } + Collections.sort(v, serializer) + val keys = serializer2.valueArrayFromArray(v.toArray()) + + fun check(keys:G, binary:ByteArray, e:E, diPos:Int){ + val v1 = serializer2.valueArraySearch(keys, e) + val v2 = serializer2.valueArraySearch(keys, e, serializer) + val v3 = Arrays.binarySearch(serializer2.valueArrayToArray(keys), e as Any, serializer as Comparator) + + assertEquals(v1, v3); + assertEquals(v1, v2); + val di = DataInput2ByteArray(binary); + val v4 = serializer2.valueArrayBinarySearch(e, di, v.size, serializer) + assertEquals(diPos, di.pos) + assertEquals(v1, v4) + } + + val out = DataOutput2ByteArray(); + serializer2.valueArraySerialize(out, keys) + val deserialized = serializer2.valueArrayDeserialize(DataInput2ByteArray(out.buf), v.size); + val diPos = out.pos + assertTrue(Arrays.deepEquals(serializer2.valueArrayToArray(keys), serializer2.valueArrayToArray(deserialized))) + + for (i in 0..max*10) { + val e = randomValue() + check(keys, out.buf, e, diPos) + } + + for(e in v){ + check(keys, out.buf, e, diPos) + } + } + + @Test open fun valueArrayGet(){ + var v = randomArray() + val keys = serializer2.valueArrayFromArray(v) + val out = DataOutput2ByteArray() + serializer2.valueArraySerialize(out, keys) + + for(i in 0 until max.toInt()){ + val v1 = v[i] as E + val v2 = serializer2.valueArrayGet(keys, i) + val v3 = serializer2.valueArrayBinaryGet(DataInput2ByteArray(out.buf), max.toInt(), i) + + assertTrue(serializer.equals(v1, v2)) + assertTrue(serializer.equals(v1, v3)) + } + + } + + open protected fun randomArray() = Array(max.toInt(), { i -> randomValue() as Any }) + + open protected fun randomValueArray() = serializer2.valueArrayFromArray(Array(arraySize.toInt(), { i -> randomValue() as Any })) + + fun cloneValueArray(vals:G):G{ + val out = DataOutput2ByteArray(); + out.pos = 0 + val size = serializer2.valueArraySize(vals) + serializer2.valueArraySerialize(out, vals); + val input = DataInput2ByteArray(out.buf) + val ret = serializer2.valueArrayDeserialize(input,size) + + assertEquals(out.pos, input.pos) + + return ret; + } + + fun assertValueArrayEquals(vals1:G, vals2:G){ + val size = serializer2.valueArraySize(vals1) + assertEquals(size, serializer2.valueArraySize(vals2)) + + for(i in 0 until size){ + val v1 = serializer2.valueArrayGet(vals1, i) + val v2 = serializer2.valueArrayGet(vals2, i) + + assertSerEquals(v1, v2) + } + } + + + @Test open fun valueArraySerDeser(){ +// TODO size hint +// if(serializer.needsAvailableSizeHint()) +// return + for(i in 0..max){ + val e = randomValueArray() + val e2 = cloneValueArray(e) + assertValueArrayEquals(e,e2) + } + } + + @Test open fun valueArrayDeleteValue(){ + for(i in 0..max){ + val vals = randomValueArray() + val valsSize = serializer2.valueArraySize(vals); + if(valsSize==0) + continue; + val pos = 1+random.nextInt(valsSize-1); + + val vals2 = serializer2.valueArrayDeleteValue(vals, pos); + assertEquals(valsSize-1, serializer2.valueArraySize(vals2)) + + val arr1 = DataIO.arrayDelete(serializer2.valueArrayToArray(vals), pos, 1); + val arr2 = serializer2.valueArrayToArray(vals2); + + arr1.forEachIndexed { i, any -> + assertSerEquals(any, arr2[i]) + } + } + + } + + @Test open fun valueArrayCopyOfRange(){ + for(i in 0..max){ + val vals = randomValueArray() + val valsSize = serializer2.valueArraySize(vals); + if(valsSize<5) + continue; + val pos = 1+random.nextInt(valsSize-4); + val vals2 = serializer2.valueArrayCopyOfRange(vals,pos,pos+3); + + val arr1a = serializer2.valueArrayToArray(vals); + val arr1 = Arrays.copyOfRange(arr1a, pos, pos+3) + + val arr2 = serializer2.valueArrayToArray(vals2); + + arr1.forEachIndexed { i, any -> + assertSerEquals(any, arr2[i]) + } + } + + } +// +// @Test fun btreemap(){ +// val ser = serializer as GroupSerializer +// val map = BTreeMap.make(keySerializer = ser, valueSerializer = Serializers.INTEGER) +// val set = TreeSet(ser); +// for(i in 1..100) +// set.add(randomValue() as Any) +// set.forEach { map.put(it,1) } +// val iter1 = set.iterator() +// val iter2 = map.keys.iterator() +// +// while(iter1.hasNext()){ +// assertTrue(iter2.hasNext()) +// assertTrue(ser.equals(iter1.next(),iter2.next())) +// } +// assertFalse(iter2.hasNext()) +// } + + @Test fun valueArrayUpdate(){ + for(i in 0..max) { + var vals = randomValueArray() + val vals2 = serializer2.valueArrayToArray(vals) + val valsSize = serializer2.valueArraySize(vals); + for (j in 0 until valsSize) { + val newVal = randomValue() + vals2[j] = newVal + vals = serializer2.valueArrayUpdateVal(vals, j, newVal) + vals2.forEachIndexed { i, any -> + assertSerEquals(any, serializer2.valueArrayGet(vals,i)) + } + } + } + } +} + +class Serializer_CHAR: GroupSerializerTest(){ + override fun randomValue() = random.nextInt().toChar() + override val serializer = Serializers.CHAR +} +// +//class Serializer_STRINGXXHASH: GroupSerializerTest(){ +// override fun randomValue() = TT.randomString(random.nextInt(10)) +// override val serializer = Serializers.STRING_ORIGHASH +//} + +class Serializer_STRING: GroupSerializerTest(){ + override fun randomValue() = TT.randomString(random.nextInt(10)) + override val serializer = Serializers.STRING +} + +//class Serializer_STRING_DELTA: GroupSerializerTest(){ +// override fun randomValue() = TT.randomString(random.nextInt(10)) +// override val serializer = Serializers.STRING_DELTA +//} +//class Serializer_STRING_DELTA2: GroupSerializerTest(){ +// override fun randomValue() = TT.randomString(random.nextInt(10)) +// override val serializer = Serializers.STRING_DELTA2 +//} +// +// +//class Serializer_STRING_INTERN: GroupSerializerTest(){ +// override fun randomValue() = TT.randomString(random.nextInt(10)) +// override val serializer = Serializers.STRING_INTERN +//} +// +//class Serializer_STRING_ASCII: GroupSerializerTest(){ +// override fun randomValue() = TT.randomString(random.nextInt(10)) +// override val serializer = Serializers.STRING_ASCII +//} +// +//class Serializer_STRING_NOSIZE: SerializerTest(){ +// override fun randomValue() = TT.randomString(random.nextInt(10)) +// override val serializer = Serializers.STRING_NOSIZE +// +//} + +class Serializer_LONG: GroupSerializerTest(){ + override fun randomValue() = random.nextLong() + override val serializer = Serializers.LONG +} + +//class Serializer_LONG_PACKED: GroupSerializerTest(){ +// override fun randomValue() = random.nextLong() +// override val serializer = Serializers.LONG_PACKED +//} +// +//class Serializer_LONG_DELTA: GroupSerializerTest(){ +// override fun randomValue() = random.nextLong() +// override val serializer = Serializers.LONG_DELTA +// override fun randomArray(): Array { +// val v = super.randomArray() +// Arrays.sort(v) +// return v +// } +// +// override fun randomValueArray(): Any { +// val v = super.randomValueArray() +// Arrays.sort(v as LongArray) +// return v +// } +//} + + + +class Serializer_INTEGER: GroupSerializerTest(){ + override fun randomValue() = random.nextInt() + override val serializer = Serializers.INTEGER +} + +//class Serializer_INTEGER_PACKED: GroupSerializerTest(){ +// override fun randomValue() = random.nextInt() +// override val serializer = Serializers.INTEGER_PACKED +//} +// +//class Serializer_INTEGER_DELTA: GroupSerializerTest(){ +// override fun randomValue() = random.nextInt() +// override val serializer = Serializers.INTEGER_DELTA +// +// override fun randomArray(): Array { +// val v = super.randomArray() +// Arrays.sort(v) +// return v +// } +// +// override fun randomValueArray(): Any { +// val v = super.randomValueArray() +// Arrays.sort(v as IntArray) +// return v +// } +// +//} + +// +//class Serializer_LONG_PACKED_ZIGZAG:SerializerTest(){ +// override fun randomValue() = random.nextLong() +// override val serializer = Serializers.LONG_PACKED_ZIGZAG +//} +// +//class Serializer_INTEGER_PACKED_ZIGZAG:SerializerTest(){ +// override fun randomValue() = random.nextInt() +// override val serializer = Serializers.INTEGER_PACKED_ZIGZAG +//} + +class Serializer_BOOLEAN: GroupSerializerTest(){ + override fun randomValue() = random.nextBoolean() + override val serializer = Serializers.BOOLEAN +} + +class Serializer_RECID: GroupSerializerTest(){ + override fun randomValue() = random.nextLong().and(0xFFFFFFFFFFFFL) //6 bytes + override val serializer = Serializers.RECID +} + +//class Serializer_RECID_ARRAY: GroupSerializerTest(){ +// override fun randomValue():LongArray { +// val ret = LongArray(random.nextInt(50)); +// for(i in 0 until ret.size){ +// ret[i] = random.nextLong().and(0xFFFFFFFFFFFFL) //6 bytes +// } +// return ret +// } +// +// override val serializer = Serializers.RECID_ARRAY +//} + +class Serializer_BYTE_ARRAY: GroupSerializerTest(){ + override fun randomValue() = TT.randomByteArray(random.nextInt(50)) + override val serializer = Serializers.BYTE_ARRAY + + @Test fun next_val(){ + fun check(b1:ByteArray?, b2:ByteArray?){ + assertArrayEquals(b1, (Serializers.BYTE_ARRAY as ByteArraySerializer).nextValue(b2)) + } + + check(byteArrayOf(1,1), byteArrayOf(1,0)) + check(byteArrayOf(2), byteArrayOf(1)) + check(byteArrayOf(2,0), byteArrayOf(1,-1)) + check(null, byteArrayOf(-1,-1)) + } +} + +// +//class Serializer_BYTE_ARRAY_DELTA: GroupSerializerTest(){ +// override fun randomValue() = TT.randomByteArray(random.nextInt(50)) +// override val serializer = Serializers.BYTE_ARRAY_DELTA +//} +// +//class Serializer_BYTE_ARRAY_DELTA2: GroupSerializerTest(){ +// override fun randomValue() = TT.randomByteArray(random.nextInt(50)) +// override val serializer = Serializers.BYTE_ARRAY_DELTA2 +//} +// +//class Serializer_BYTE_ARRAY_NOSIZE: SerializerTest(){ +// override fun randomValue() = TT.randomByteArray(random.nextInt(50)) +// override val serializer = Serializers.BYTE_ARRAY_NOSIZE +// +//} + + +class Serializer_BYTE: GroupSerializerTest(){ + override fun randomValue() = random.nextInt().toByte() + override val serializer = Serializers.BYTE +} + +class Serializer_CHAR_ARRAY: GroupSerializerTest(){ + override fun randomValue():CharArray { + val ret = CharArray(random.nextInt(50)); + for(i in 0 until ret.size){ + ret[i] = random.nextInt().toChar() + } + return ret + } + override val serializer = Serializers.CHAR_ARRAY +// +// @Test fun prefix_submap(){ +// val map = BTreeMap.make(keySerializer = serializer, valueSerializer = Serializers.STRING) +// for(i in 'a'..'f') for(j in 'a'..'f') { +// map.put(charArrayOf(i, j), "$i-$j") +// } +// +// //zero subMap +// assertEquals(0, map.prefixSubMap(charArrayOf('z')).size) +// +// var i = 'b'; +// val sub = map.prefixSubMap(charArrayOf(i)) +// assertEquals(6, sub.size) +// for(j in 'a'..'f') +// assertEquals("$i-$j", sub[charArrayOf(i,j)]) +// +// //out of subMap range +// assertNull(sub[charArrayOf('b','z')]) +// +// //max case +// i = java.lang.Character.MAX_VALUE; +// for(j in 'a'..'f') +// map.put(charArrayOf(i, j), "$i-$j") +// +// val subMax = map.prefixSubMap(charArrayOf(i)) +// assertEquals(6, subMax.size) +// for(j in 'a'..'f') +// assertEquals("$i-$j", subMax[charArrayOf(i,j.toChar())]) +// +// //out of subMap range +// assertNull(sub[charArrayOf(i,'z')]) +// +// //max-max case +// map.put(charArrayOf(i, i), "$i-$i") +// +// val subMaxMax = map.prefixSubMap(charArrayOf(i, i)) +// assertEquals("$i-$i", subMaxMax[charArrayOf(i,i)]) +// +// //out of subMaxMax range +// assertNull(subMaxMax[charArrayOf(i,'a')]) +// +// //min case +// i = java.lang.Character.MIN_VALUE; +// for(j in 'a'..'f') +// map.put(charArrayOf(i, j.toChar()), "$i-$j") +// +// val subMin = map.prefixSubMap(charArrayOf(i)) +// assertEquals(6, subMin.size) +// for(j in 'a'..'f') +// assertEquals("$i-$j", subMin[charArrayOf(i,j)]) +// +// //out of subMap range +// assertNull(sub[charArrayOf('a','z')]) +// +// //min-min case +// map.put(charArrayOf(i, i), "$i-$i") +// +// val subMinMin = map.prefixSubMap(charArrayOf(i, i)) +// assertEquals("$i-$i", subMinMin[charArrayOf(i,i)]) +// +// //out of subMinMin range +// assertNull(subMinMin[charArrayOf(i,'a')]) +// } +} + +class Serializer_INT_ARRAY: GroupSerializerTest(){ + override fun randomValue():IntArray { + val ret = IntArray(random.nextInt(50)); + for(i in 0 until ret.size){ + ret[i] = random.nextInt() + } + return ret + } + override val serializer = Serializers.INT_ARRAY +// +// @Test fun prefix_submap(){ +// val map = BTreeMap.make(keySerializer = serializer, valueSerializer = Serializers.STRING) +// for(i in 1..10) for(j in 1..10) { +// map.put(intArrayOf(i, j), "$i-$j") +// } +// +// //zero subMap +// assertEquals(0, map.prefixSubMap(intArrayOf(15)).size) +// +// var i = 5; +// val sub = map.prefixSubMap(intArrayOf(i)) +// assertEquals(10, sub.size) +// for(j in 1..10) +// assertEquals("$i-$j", sub[intArrayOf(i,j)]) +// +// //out of subMap range +// assertNull(sub[intArrayOf(3,5)]) +// +// //max case +// i = Int.MAX_VALUE; +// for(j in 1..10) +// map.put(intArrayOf(i, j), "$i-$j") +// +// val subMax = map.prefixSubMap(intArrayOf(i)) +// assertEquals(10, subMax.size) +// for(j in 1..10) +// assertEquals("$i-$j", subMax[intArrayOf(i,j)]) +// +// //out of subMap range +// assertNull(sub[intArrayOf(3,5)]) +// +// //max-max case +// map.put(intArrayOf(i, i), "$i-$i") +// +// val subMaxMax = map.prefixSubMap(intArrayOf(i, i)) +// assertEquals("$i-$i", subMaxMax[intArrayOf(i,i)]) +// +// //out of subMaxMax range +// assertNull(subMaxMax[intArrayOf(i,5)]) +// +// //min case +// i = Int.MIN_VALUE; +// for(j in 1..10) +// map.put(intArrayOf(i, j), "$i-$j") +// +// val subMin = map.prefixSubMap(intArrayOf(i)) +// assertEquals(10, subMin.size) +// for(j in 1..10) +// assertEquals("$i-$j", subMin[intArrayOf(i,j)]) +// +// //out of subMap range +// assertNull(sub[intArrayOf(3,5)]) +// +// //min-min case +// map.put(intArrayOf(i, i), "$i-$i") +// +// val subMinMin = map.prefixSubMap(intArrayOf(i, i)) +// assertEquals("$i-$i", subMinMin[intArrayOf(i,i)]) +// +// //out of subMinMin range +// assertNull(subMinMin[intArrayOf(i,5)]) +// } +} + + +class Serializer_LONG_ARRAY: GroupSerializerTest(){ + override fun randomValue():LongArray { + val ret = LongArray(random.nextInt(30)); + for(i in 0 until ret.size){ + ret[i] = random.nextLong() + } + return ret + } + override val serializer = Serializers.LONG_ARRAY +// +// @Test fun prefix_submap(){ +// val map = BTreeMap.make(keySerializer = serializer, valueSerializer = Serializers.STRING) +// for(i in 1L..10L) for(j in 1L..10L) { +// map.put(longArrayOf(i, j), "$i-$j") +// } +// +// //zero subMap +// assertEquals(0, map.prefixSubMap(longArrayOf(15)).size) +// +// var i = 5L; +// val sub = map.prefixSubMap(longArrayOf(i)) +// assertEquals(10, sub.size) +// for(j in 1L..10L) +// assertEquals("$i-$j", sub[longArrayOf(i,j)]) +// +// //out of subMap range +// assertNull(sub[longArrayOf(3,5)]) +// +// //max case +// i = Long.MAX_VALUE; +// for(j in 1L..10L) +// map.put(longArrayOf(i, j), "$i-$j") +// +// val subMax = map.prefixSubMap(longArrayOf(i)) +// assertEquals(10, subMax.size) +// for(j in 1L..10L) +// assertEquals("$i-$j", subMax[longArrayOf(i,j)]) +// +// //out of subMap range +// assertNull(sub[longArrayOf(3,5)]) +// +// //max-max case +// map.put(longArrayOf(i, i), "$i-$i") +// +// val subMaxMax = map.prefixSubMap(longArrayOf(i, i)) +// assertEquals("$i-$i", subMaxMax[longArrayOf(i,i)]) +// +// //out of subMaxMax range +// assertNull(subMaxMax[longArrayOf(i,5)]) +// +// //min case +// i = Long.MIN_VALUE; +// for(j in 1L..10L) +// map.put(longArrayOf(i, j), "$i-$j") +// +// val subMin = map.prefixSubMap(longArrayOf(i)) +// assertEquals(10, subMin.size) +// for(j in 1L..10L) +// assertEquals("$i-$j", subMin[longArrayOf(i,j)]) +// +// //out of subMap range +// assertNull(sub[longArrayOf(3,5)]) +// +// //min-min case +// map.put(longArrayOf(i, i), "$i-$i") +// +// val subMinMin = map.prefixSubMap(longArrayOf(i, i)) +// assertEquals("$i-$i", subMinMin[longArrayOf(i,i)]) +// +// //out of subMinMin range +// assertNull(subMinMin[longArrayOf(i,5)]) +// } +} + +class Serializer_DOUBLE_ARRAY: GroupSerializerTest(){ + override fun randomValue():DoubleArray { + val ret = DoubleArray(random.nextInt(30)); + for(i in 0 until ret.size){ + ret[i] = random.nextDouble() + } + return ret + } + override val serializer = Serializers.DOUBLE_ARRAY +} + + +class Serializer_JAVA: GroupSerializerTest>(){ + override fun randomValue() = TT.randomString(10) + override val serializer = Serializers.JAVA + + override val repeat: Int = 3 + + internal class Object2 : Serializable + + open internal class CollidingObject(val value: String) : Serializable { + override fun hashCode(): Int { + return this.value.hashCode() and 1 + } + + override fun equals(obj: Any?): Boolean { + return obj is CollidingObject && obj.value == value + } + } + + internal class ComparableCollidingObject(value: String) : CollidingObject(value), Comparable, Serializable { + override fun compareTo(o: ComparableCollidingObject): Int { + return value.compareTo(o.value) + } + } + + @Test fun clone1(){ + val v = TT.clone(Object2(), Serializers.JAVA) + assertTrue(v is Object2) + } + + @Test fun clone2(){ + val v = TT.clone(CollidingObject("111"), Serializers.JAVA) + assertTrue(v is CollidingObject) + assertSerEquals("111", (v as CollidingObject).value) + } + + @Test fun clone3(){ + val v = TT.clone(ComparableCollidingObject("111"), Serializers.JAVA) + assertTrue(v is ComparableCollidingObject) + assertSerEquals("111", (v as ComparableCollidingObject).value) + + } + +} + + +// +//class Serializer_ELSA: GroupSerializerTest(){ +// override fun randomValue() = TT.randomString(10) +// override val serializer = Serializers.ELSA +// +// internal class Object2 : Serializable +// +// open internal class CollidingObject(val value: String) : Serializable { +// override fun hashCode(): Int { +// return this.value.hashCode() and 1 +// } +// +// override fun equals(obj: Any?): Boolean { +// return obj is CollidingObject && obj.value == value +// } +// } +// +// internal class ComparableCollidingObject(value: String) : CollidingObject(value), Comparable, Serializable { +// override fun compareTo(o: ComparableCollidingObject): Int { +// return value.compareTo(o.value) +// } +// } +// +// @Test fun clone1(){ +// val v = TT.clone(Object2(), Serializers.ELSA) +// assertTrue(v is Object2) +// } +// +// @Test fun clone2(){ +// val v = TT.clone(CollidingObject("111"), Serializers.ELSA) +// assertTrue(v is CollidingObject) +// assertSerEquals("111", (v as CollidingObject).value) +// } +// +// @Test fun clone3(){ +// val v = TT.clone(ComparableCollidingObject("111"), Serializers.ELSA) +// assertTrue(v is ComparableCollidingObject) +// assertSerEquals("111", (v as ComparableCollidingObject).value) +// +// } +// +//} +// + + +//class Serializer_DB_default: GroupSerializerTest(){ +// override fun randomValue() = TT.randomString(11) +// override val serializer = DBMaker.memoryDB().make().defaultSerializer +// +// @Test override fun trusted(){ +// } +//} +// + +class Serializer_UUID: GroupSerializerTest(){ + override fun randomValue() = UUID(random.nextLong(), random.nextLong()) + override val serializer = Serializers.UUID +} + +class Serializer_FLOAT: GroupSerializerTest(){ + override fun randomValue() = random.nextFloat() + override val serializer = Serializers.FLOAT +} + +class Serializer_FLOAT_ARRAY: GroupSerializerTest(){ + override fun randomValue():FloatArray { + val ret = FloatArray(random.nextInt(50)); + for(i in 0 until ret.size){ + ret[i] = random.nextFloat() + } + return ret + } + override val serializer = Serializers.FLOAT_ARRAY +} + + + +class Serializer_DOUBLE: GroupSerializerTest(){ + override fun randomValue() = random.nextDouble() + override val serializer = Serializers.DOUBLE +} + +class Serializer_SHORT: GroupSerializerTest(){ + override fun randomValue() = random.nextInt().toShort() + override val serializer = Serializers.SHORT +} + +class Serializer_SHORT_ARRAY: GroupSerializerTest(){ + override fun randomValue():ShortArray { + val ret = ShortArray(random.nextInt(50)); + for(i in 0 until ret.size){ + ret[i] = random.nextInt().toShort() + } + return ret + } + override val serializer = Serializers.SHORT_ARRAY + +// @Test fun prefix_submap(){ +// val map = BTreeMap.make(keySerializer = serializer, valueSerializer = Serializers.STRING) +// for(i in 1..10) for(j in 1..10) { +// map.put(shortArrayOf(i.toShort(), j.toShort()), "$i-$j") +// } +// +// //zero subMap +// assertEquals(0, map.prefixSubMap(shortArrayOf(15)).size) +// +// var i = 5.toShort(); +// val sub = map.prefixSubMap(shortArrayOf(i)) +// assertEquals(10, sub.size) +// for(j in 1..10) +// assertEquals("$i-$j", sub[shortArrayOf(i,j.toShort())]) +// +// //out of subMap range +// assertNull(sub[shortArrayOf(3,5)]) +// +// //max case +// i = Short.MAX_VALUE; +// for(j in 1..10) +// map.put(shortArrayOf(i, j.toShort()), "$i-$j") +// +// val subMax = map.prefixSubMap(shortArrayOf(i)) +// assertEquals(10, subMax.size) +// for(j in 1..10) +// assertEquals("$i-$j", subMax[shortArrayOf(i,j.toShort())]) +// +// //out of subMap range +// assertNull(sub[shortArrayOf(3,5)]) +// +// //max-max case +// map.put(shortArrayOf(i, i), "$i-$i") +// +// val subMaxMax = map.prefixSubMap(shortArrayOf(i, i)) +// assertEquals("$i-$i", subMaxMax[shortArrayOf(i,i)]) +// +// //out of subMaxMax range +// assertNull(subMaxMax[shortArrayOf(i,5)]) +// +// //min case +// i = Short.MIN_VALUE; +// for(j in 1..10) +// map.put(shortArrayOf(i, j.toShort()), "$i-$j") +// +// val subMin = map.prefixSubMap(shortArrayOf(i)) +// assertEquals(10, subMin.size) +// for(j in 1..10) +// assertEquals("$i-$j", subMin[shortArrayOf(i,j.toShort())]) +// +// //out of subMap range +// assertNull(sub[shortArrayOf(3,5)]) +// +// //min-min case +// map.put(shortArrayOf(i, i), "$i-$i") +// +// val subMinMin = map.prefixSubMap(shortArrayOf(i, i)) +// assertEquals("$i-$i", subMinMin[shortArrayOf(i,i)]) +// +// //out of subMinMin range +// assertNull(subMinMin[shortArrayOf(i,5)]) +// } +} + +class Serializer_BIG_INTEGER: GroupSerializerTest(){ + override fun randomValue() = BigInteger(random.nextInt(50), random) + override val serializer = Serializers.BIG_INTEGER +} + +class Serializer_BIG_DECIMAL: GroupSerializerTest(){ + override fun randomValue() = BigDecimal(BigInteger(random.nextInt(50), random), random.nextInt(100)) + override val serializer = Serializers.BIG_DECIMAL +} + +class Serializer_DATE: GroupSerializerTest(){ + override fun randomValue() = Date(random.nextLong()) + override val serializer = Serializers.DATE +} + + +//class SerializerCompressionWrapperTest(): GroupSerializerTest(){ +// override fun randomValue() = TT.randomByteArray(random.nextInt(1000)) +// +// override val serializer = SerializerCompressionWrapper(Serializers.BYTE_ARRAY as GroupSerializer) +// +// @Test +// fun compression_wrapper() { +// var b = ByteArray(100) +// Random().nextBytes(b) +// assertTrue(Serializers.BYTE_ARRAY.equals(b, TT.clone(b, serializer))) +// +// b = Arrays.copyOf(b, 10000) +// assertTrue(Serializers.BYTE_ARRAY.equals(b, TT.clone(b, serializer))) +// +// val out = DataOutput2() +// serializer.serialize(out, b) +// assertTrue(out.pos < 1000) +// } +// +//} +// +//class Serializer_DeflateWrapperTest(): GroupSerializerTest() { +// override fun randomValue() = TT.randomByteArray(random.nextInt(1000)) +// override val serializer = SerializerCompressionDeflateWrapper(Serializers.BYTE_ARRAY as GroupSerializer) +// +// +// @Test fun deflate_wrapper() { +// val c = SerializerCompressionDeflateWrapper(Serializers.BYTE_ARRAY as GroupSerializer, -1, +// byteArrayOf(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 4, 5, 6, 7, 8, 9, 65, 2)) +// +// val b = byteArrayOf(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 3, 3, 3, 3, 35, 6, 67, 7, 3, 43, 34) +// +// assertTrue(Arrays.equals(b, TT.clone(b, c))) +// } +// +//} +// +// +//open class Serializer_Array(): GroupSerializerTest>(){ +// override fun randomValue() = Array(random.nextInt(30), { TT.randomString(random.nextInt(30))}) +// +// override val serializer = SerializerArray(Serializers.STRING as Serializer) +// +// @Test fun array() { +// val s: Serializer> = SerializerArray(Serializers.INTEGER as Serializer) +// +// val a:Array = arrayOf(1, 2, 3, 4) +// +// assertTrue(Arrays.equals(a, TT.clone(a, s))) +// } +// +//} +// +// +//class Serializer_DeltaArray(): Serializer_Array(){ +// +// //TODO more tests with common prefix +// +// override val serializer = SerializerArrayDelta(Serializers.STRING as Serializer) +// +// +//} +// +// +// +//class Serializer_ArrayTuple(): GroupSerializerTest>(){ +// +// override fun randomValue() = arrayOf(intArrayOf(random.nextInt()), longArrayOf(random.nextLong())) +// +// override val serializer = SerializerArrayTuple(Serializers.INT_ARRAY, Serializers.LONG_ARRAY) +// +// +// @Test fun prefix_submap(){ +// val map = BTreeMap.make(keySerializer = SerializerArrayTuple(Serializers.INTEGER, Serializers.LONG), valueSerializer = Serializers.STRING) +// for(i in 1..10) for(j in 1L..10) +// map.put(arrayOf(i as Any,j as Any),"$i-$j") +// +// val sub = map.prefixSubMap(arrayOf(5)) +// assertEquals(10, sub.size) +// for(j in 1L..10) +// assertEquals("5-$j", sub[arrayOf(5 as Any,j as Any)]) +// +// assertNull(sub[arrayOf(3 as Any,5 as Any)]) +// } +// +// @Test fun prefix_comparator(){ +// val s = SerializerArrayTuple(Serializers.INTEGER, Serializers.INTEGER) +// assertEquals(-1, s.compare(arrayOf(-1), arrayOf(1))) +// assertEquals(1, s.compare(arrayOf(2), arrayOf(1, null))) +// assertEquals(-1, s.compare(arrayOf(1), arrayOf(1, null))) +// assertEquals(-1, s.compare(arrayOf(1), arrayOf(2, null))) +// assertEquals(-1, s.compare(arrayOf(1,2), arrayOf(1, null))) +// +// assertEquals(1, s.compare(arrayOf(2), arrayOf(1, 1))) +// assertEquals(-1, s.compare(arrayOf(1), arrayOf(1, 1))) +// assertEquals(-1, s.compare(arrayOf(1), arrayOf(2, 1))) +// assertEquals(1, s.compare(arrayOf(1,2), arrayOf(1, 1))) +// assertEquals(-1, s.compare(arrayOf(1), arrayOf(1, 2))) +// } +//} + + + + +class SerializerUtilsTest(){ + @Test fun lookup(){ + assertEquals(Serializers.LONG, SerializerUtils.serializerForClass(Long::class.java)) + assertEquals(Serializers.LONG_ARRAY, SerializerUtils.serializerForClass(LongArray::class.java)) + assertEquals(Serializers.UUID, SerializerUtils.serializerForClass(UUID::class.java)) + assertEquals(Serializers.STRING, SerializerUtils.serializerForClass(String::class.java)) + assertNull(SerializerUtils.serializerForClass(Serializer::class.java)) + } + +} diff --git a/src/test/java/org/mapdb/ser/SerializersJavaAccessTest.java b/src/test/java/org/mapdb/ser/SerializersJavaAccessTest.java new file mode 100644 index 000000000..d8a827141 --- /dev/null +++ b/src/test/java/org/mapdb/ser/SerializersJavaAccessTest.java @@ -0,0 +1,31 @@ +package org.mapdb.ser; + +import org.junit.Test; +import org.mapdb.io.DataOutput2ByteArray; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class SerializersJavaAccessTest { + + @Test + public void check_accessible() { + assertTrue(Serializers.INTEGER instanceof Serializer); + + assertTrue(Serializers.BYTE_ARRAY instanceof Serializer); + } + + @Test + public void integer() throws IOException { + DataOutput2ByteArray out = new DataOutput2ByteArray(); + + Integer i = new Integer(10); + Serializers.INTEGER.serialize(out, i); + assertEquals(out.pos, 4); + } + + +} + diff --git a/src/test/java/org/mapdb/ser/SerializersTest.kt b/src/test/java/org/mapdb/ser/SerializersTest.kt new file mode 100644 index 000000000..856680ea0 --- /dev/null +++ b/src/test/java/org/mapdb/ser/SerializersTest.kt @@ -0,0 +1,84 @@ +package org.mapdb.ser + +import io.kotlintest.matchers.beGreaterThan +import io.kotlintest.matchers.beLessThan +import io.kotlintest.properties.forAll +import io.kotlintest.should +import org.mapdb.DBWordSpec +import org.mapdb.TT + +class SerializersTest : DBWordSpec({ + + val sers = Serializers::class.java.fields + .filter { it.name != "INSTANCE" } //TODO remove this field from java + .map { Pair(it.name, it.get(null) as Serializer) } + + assert(sers.isNotEmpty()) + + + for ((name, ser) in sers) { + name should { + val gen = TT.genFor(ser.serializedType()) + "equals after clone "{ + forAll(gen) { a -> + val b = Serializers.clone(a, ser) + ser.equals(a, b) + } + } + "hash after clone"{ + forAll(gen) { a -> + val b = Serializers.clone(a, ser) + ser.hashCode(a) == ser.hashCode(b!!) + } + } + + "equals not constant"{ + forAll(gen, gen) { a, b -> + Serializers.binaryEqual(ser, a, b) == ser.equals(a, b) + } + } + + + "hash not constant"{ + forAll(gen, gen) { a, b -> + Serializers.binaryEqual(ser, a, b) == (ser.hashCode(a) == ser.hashCode(b)) + } + } + + + if(!TT.shortTest()){ + "hash variance and collisions"{ + val slotsCount = 100_000 + val hashCount = 1e9.toLong() + val variance = LongArray(slotsCount) + val collisions = LongArray(slotsCount) + val iter = gen.random().iterator() + for(i in 0L until hashCount){ + val r = iter.next() + val hash = r.hashCode() + + // use div, to check its distributed from Integer.MIN_VALUE to Integer.MAX_VALUE + variance[Math.abs(hash / slotsCount)]++ + // use modulo to check for hash collisions + collisions[Math.abs(hash % slotsCount)]++ + + } + + for(c in collisions){ + c.toDouble() should beGreaterThan(0.1 * hashCount/slotsCount) + } + + val lowVarCount = variance.filter{it< 0.0001 * hashCount/slotsCount }.size + // 80% for almost empty hashes slots seems like too much, perhaps problem in random generator? + lowVarCount.toDouble() should beLessThan(0.8 * slotsCount) + + } + } + } + } + +}) + +fun serializersAll(): List> { + return arrayListOf() +} \ No newline at end of file diff --git a/src/test/java/org/mapdb/store/StoreReopenTest.kt b/src/test/java/org/mapdb/store/StoreReopenTest.kt new file mode 100644 index 000000000..7bd2ce6b8 --- /dev/null +++ b/src/test/java/org/mapdb/store/StoreReopenTest.kt @@ -0,0 +1,187 @@ +package org.mapdb.store + +import io.kotlintest.shouldBe +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test +import org.mapdb.TT +import org.mapdb.ser.Serializers +import org.mapdb.store.legacy.Store2 +import org.mapdb.store.legacy.StoreDirect +import org.mapdb.store.legacy.Volume +import java.io.File +import java.util.* + + +class FileHeapBufStoreTest : StoreReopenTest() { + override fun openStore(f:File) = FileHeapBufStore(f) +} + +class FileHeapBufStoreRWLockTest : StoreReopenTest() { + override fun openStore(f:File) = FileHeapBufStoreRWLock(f) +} + +class LegacyStoreDirectTest : StoreReopenTest() { + override fun openStore(f:File) = StoreDirect(Volume.fileFactory(f,1,false,0, Store2.VOLUME_CHUNK_SHIFT,1024)) +} + +abstract class StoreReopenTest(): StoreTest(){ + + + override fun openStore(): Store { + val f = TT.tempFile() + return openStore(f) + } + + @Test fun reopen(){ + TT.withTempFile { f-> + var s = openStore(f) + val recid = s.put("aa", Serializers.STRING) + s.commit() + s.close() + + s = openStore(f) + s.get(recid,Serializers.STRING) shouldBe "aa" + s.close() + } + } + + + abstract fun openStore(file: File): Store +// +// abstract val headerType:Long + +// TODO file headers +// +// @Test open fun headerType(){ +// val s = openStore(file) +// s.put(11L, Serializers.LONG) +// s.commit() +// s.close() +// val vol = RandomAccessFileVol.FACTORY.makeVolume(file.path, true) +// assertEquals(CC.FILE_HEADER,vol.getUnsignedByte(0L).toLong()) +// assertEquals(headerType, vol.getUnsignedByte(1L).toLong()) +// } + + + + @Test fun put_reopen_get() { + TT.withTempFile { file -> + var e = openStore(file) + val l = 11231203099090L + val recid = e.put(l, Serializers.LONG) + e.commit() + e.close() + e = openStore(file) + + assertEquals(l, e.get(recid, Serializers.LONG)) + e.close() + } + } + + + @Test fun put_reopen_get_large() { + TT.withTempFile { file -> + var e = openStore(file) + + val b = TT.randomByteArray(1000000) + val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) + e.commit() + e.close() + e = openStore(file) + + assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE))) + e.verify() + e.close() + } + } + + @Test fun large_record_update2() { + TT.withTempFile { file -> + var e = openStore(file) + val b = TT.randomByteArray(1000000) + val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) + e.update(recid, Serializers.BYTE_ARRAY_NOSIZE, b) + var b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(b, b2)) + e.commit() + e.close() + e = openStore(file) + + b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(b, b2)) + e.verify() + e.close() + } + } + + @Test fun large_record_larger() { + if(TT.shortTest()) + return + TT.withTempFile { file -> + var e = openStore(file) + val b = TT.randomByteArray(100000000) + val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) + var b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(b, b2)) + e.verify() + e.commit() + e.close() + e = openStore(file) + + b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(b, b2)) + e.verify() + e.close() + } + } + + + + @Test fun test_store_reopen() { + TT.withTempFile { file -> + var e = openStore(file) + val recid = e.put("aaa", Serializers.STRING) + e.commit() + e.commit() + e.close() + e = openStore(file) + val aaa = e.get(recid, Serializers.STRING) + assertEquals("aaa", aaa) + e.verify() + e.close() + } + } + +// TODO file locking +// @Test fun file_lock(){ +// TT.withTempFile { file -> +// var e = openStore(file) +// val recid = e.put("aaa", Serializers.STRING) +// +// assertFailsWith(DBException.FileLocked::class) { +// openStore(file) +// } +// +// e.close() +// } +// } +// TODO missing test +// @Test fun empty_rollback2(){ +// val e = openStore(file) +// if(e is StoreTx) +// e.rollback() +// e.close() +// } + + @Test fun empty_commit2(){ + TT.withTempFile { file -> + val e = openStore(file) + e.commit() + e.close() + } + } + + + +} \ No newline at end of file diff --git a/src/test/java/org/mapdb/store/StoreTest.kt b/src/test/java/org/mapdb/store/StoreTest.kt new file mode 100644 index 000000000..d9c9978e8 --- /dev/null +++ b/src/test/java/org/mapdb/store/StoreTest.kt @@ -0,0 +1,717 @@ +package org.mapdb.store + +import io.kotlintest.shouldBe +import org.eclipse.collections.impl.list.mutable.primitive.LongArrayList +import org.eclipse.collections.impl.map.mutable.primitive.LongObjectHashMap +import org.junit.Assert.* +import org.junit.Test +import org.mapdb.DBException +import org.mapdb.TT +import org.mapdb.io.DataIO +import org.mapdb.io.DataInput2 +import org.mapdb.io.DataOutput2 +import org.mapdb.ser.Serializer +import org.mapdb.ser.Serializers +import org.mapdb.ser.Serializers.LONG +import org.mapdb.store.li.LiStore +import java.util.* +import java.util.concurrent.atomic.AtomicLong + + + +class HeapBufStoreTest : StoreTest() { + override fun openStore() = HeapBufStore() +} +class HeapBufStoreRWLockTest : StoreTest() { + override fun openStore() = HeapBufStoreRWLock() +} + + + +class ConcMapStoreTest : StoreTest() { + override fun openStore() = ConcMapStore() + + override fun recid_getAll_sorted(){ + //TODO support multiform store + } + +} + +class LiStoreTest : StoreTest() { + override fun openStore() = LiStore() +} + + + +/** + * Tests contract on `Store` interface + */ +abstract class StoreTest { + + abstract fun openStore(): Store + + @Test fun put_get() { + val e = openStore() + val l = 11231203099090L + val recid = e.put(l, LONG) + assertEquals(l, e.get(recid, LONG)) + e.verify() + e.close() + } + + @Test fun put_get_large() { + val e = openStore() + if(e.maxRecordSize()<1e6) + return + + val b = TT.randomByteArray(1000000) + Random().nextBytes(b) + val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE))) + e.verify() + e.close() + } + + @Test fun testSetGet() { + val e = openStore() + val recid = e.put(10000.toLong(), LONG) + val s2 = e.get(recid, LONG) + assertEquals(s2, java.lang.Long.valueOf(10000)) + e.verify() + e.close() + } + + + @Test fun reserved_recids(){ + val e = openStore() + for(expectedRecid in 1 .. Recids.RECID_MAX_RESERVED){ + val allocRecid = e.preallocate() + assertEquals(expectedRecid, allocRecid) + } + e.verify() + e.close() + } + + @Test + fun large_record() { + val e = openStore() + if(e.maxRecordSize()<1e6) + return + + val b = TT.randomByteArray(100000) + val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) + val b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(b, b2)) + e.verify() + e.close() + } + + @Test fun large_record_delete() { + val e = openStore() + if(e.maxRecordSize()<1e6) + return + val b = TT.randomByteArray(100000) + val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) + e.verify() + e.delete(recid, Serializers.BYTE_ARRAY_NOSIZE) + e.verify() + e.close() + } + + + @Test fun large_record_delete2(){ + val s = openStore() + if(s.maxRecordSize()<1e6) + return + + val b = TT.randomByteArray(200000) + val recid1 = s.put(b, Serializers.BYTE_ARRAY_NOSIZE) + s.verify() + val b2 = TT.randomByteArray(220000) + val recid2 = s.put(b2, Serializers.BYTE_ARRAY_NOSIZE) + s.verify() + + assertTrue(Arrays.equals(b, s.get(recid1, Serializers.BYTE_ARRAY_NOSIZE))) + assertTrue(Arrays.equals(b2, s.get(recid2, Serializers.BYTE_ARRAY_NOSIZE))) + + s.delete(recid1, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(b2, s.get(recid2, Serializers.BYTE_ARRAY_NOSIZE))) + s.verify() + + s.delete(recid2, Serializers.BYTE_ARRAY_NOSIZE) + s.verify() + + s.verify() + s.close() + } + + @Test fun large_record_update(){ + val s = openStore() + if(s.maxRecordSize()<1e6) + return + + var b = TT.randomByteArray(200000) + val recid1 = s.put(b, Serializers.BYTE_ARRAY_NOSIZE) + s.verify() + val b2 = TT.randomByteArray(220000) + val recid2 = s.put(b2, Serializers.BYTE_ARRAY_NOSIZE) + s.verify() + + assertTrue(Arrays.equals(b, s.get(recid1, Serializers.BYTE_ARRAY_NOSIZE))) + assertTrue(Arrays.equals(b2, s.get(recid2, Serializers.BYTE_ARRAY_NOSIZE))) + + b = TT.randomByteArray(210000) + s.update(recid1, Serializers.BYTE_ARRAY_NOSIZE, b); + assertTrue(Arrays.equals(b, s.get(recid1, Serializers.BYTE_ARRAY_NOSIZE))) + assertTrue(Arrays.equals(b2, s.get(recid2, Serializers.BYTE_ARRAY_NOSIZE))) + s.verify() + + b = TT.randomByteArray(28001) + s.update(recid1, Serializers.BYTE_ARRAY_NOSIZE, b); + assertTrue(Arrays.equals(b, s.get(recid1, Serializers.BYTE_ARRAY_NOSIZE))) + assertTrue(Arrays.equals(b2, s.get(recid2, Serializers.BYTE_ARRAY_NOSIZE))) + s.verify() + + s.close() + } + + + @Test + fun get_non_existent() { + val e = openStore() + + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.get(1, TT.Serializer_ILLEGAL_ACCESS) + } + + e.verify() + e.close() + } + + @Test fun preallocate_cas() { + val e = openStore() + val recid = e.preallocate() + e.verify() + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + e.compareAndUpdate(recid, LONG, 1L, 2L) + } + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + e.compareAndUpdate(recid, LONG, 2L, 2L) + } + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + e.get(recid, LONG) + } + + e.preallocatePut(recid, LONG, 2L) + + assertFalse(e.compareAndUpdate(recid, LONG, 1L, 3L)) + assertTrue(e.compareAndUpdate(recid, LONG, 2L, 2L)) + assertTrue(e.compareAndUpdate(recid, LONG, 2L, 3L)) + assertEquals(3L, e.get(recid, LONG)) + + e.verify() + e.close() + } + + @Test fun preallocate_get_update_delete_update_get() { + val e = openStore() + val recid = e.preallocate() + e.verify() + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + e.get(recid, TT.Serializer_ILLEGAL_ACCESS) + } + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + e.update(recid, LONG, 1L) + } + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + assertEquals(1L.toLong(), e.get(recid, LONG)) + } + e.preallocatePut(recid, LONG, 1L) + assertEquals(1L.toLong(), e.get(recid, LONG)) + + e.delete(recid, LONG) + TT.assertFailsWith(DBException.RecordNotFound::class) { + assertNull(e.get(recid, TT.Serializer_ILLEGAL_ACCESS)) + } + e.verify() + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.update(recid, LONG, 1L) + } + e.verify() + e.close() + } + + @Test fun cas_delete() { + val e = openStore() + val recid = e.put(1L, LONG) + e.verify() + assertTrue(e.compareAndDelete(recid, LONG, 1L)) + + TT.assertFailsWith(DBException.RecordNotFound::class) { + assertNull(e.get(recid, TT.Serializer_ILLEGAL_ACCESS)) + } + e.verify() + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.update(recid, LONG, 1L) + } + e.verify() + e.close() + } + + + @Test fun cas_prealloc() { + val e = openStore() + val recid = e.preallocate() + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + e.compareAndUpdate(recid, LONG, 2L, 1L) + } + e.preallocatePut(recid, LONG, 2L) + assertTrue(e.compareAndUpdate(recid, LONG, 2L, 1L)) + e.verify() + assertEquals(1L, e.get(recid, LONG)) + assertTrue(e.compareAndUpdate(recid, LONG, 1L, 3L)) + e.verify() + assertEquals(3L, e.get(recid, LONG)) + e.verify() + e.close() + } + + @Test fun cas_prealloc_delete() { + val e = openStore() + val recid = e.preallocate() + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + e.delete(recid, LONG) + } + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + e.get(recid, LONG) + } + e.preallocatePut(recid, LONG, 1L) + + e.delete(recid, LONG) + TT.assertFailsWith(DBException.RecordNotFound::class) { + assertTrue(e.compareAndUpdate(recid, LONG, 3L, 1L)) + } + e.verify() + e.close() + } + + @Test fun putGetUpdateDelete() { + val e = openStore() + var s = "aaaad9009" + val recid = e.put(s, Serializers.STRING) + + assertEquals(s, e.get(recid, Serializers.STRING)) + + s = "da8898fe89w98fw98f9" + e.update(recid, Serializers.STRING, s) + assertEquals(s, e.get(recid, Serializers.STRING)) + e.verify() + e.delete(recid, Serializers.STRING) + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.get(recid, Serializers.STRING) + } + e.verify() + e.close() + } + + + @Test fun not_preallocated() { + val e = openStore() + TT.assertFailsWith(DBException.RecordNotPreallocated::class) { + e.preallocatePut(222, LONG, 1L) + } + val recid = e.put(1L, LONG) + TT.assertFailsWith(DBException.RecordNotPreallocated::class) { + e.preallocatePut(recid, LONG, 1L) + } + } + + @Test fun nosize_array() { + val e = openStore() + var b = ByteArray(0) + val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE))) + + b = byteArrayOf(1, 2, 3) + e.update(recid, Serializers.BYTE_ARRAY_NOSIZE, b) + assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE))) + e.verify() + b = byteArrayOf() + e.update(recid, Serializers.BYTE_ARRAY_NOSIZE, b) + assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE))) + e.verify() + e.delete(recid, Serializers.BYTE_ARRAY_NOSIZE) + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) + } + e.verify() + e.close() + } + + + @Test fun nosize_array_prealloc() { + val e = openStore() + var b = ByteArray(0) + val recid = e.preallocate(); + e.preallocatePut(recid, Serializers.BYTE_ARRAY_NOSIZE, b) + assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE))) + + b = byteArrayOf(1, 2, 3) + e.update(recid, Serializers.BYTE_ARRAY_NOSIZE, b) + assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE))) + e.verify() + b = byteArrayOf() + e.update(recid, Serializers.BYTE_ARRAY_NOSIZE, b) + assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE))) + e.verify() + e.delete(recid, Serializers.BYTE_ARRAY_NOSIZE) + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) + } + e.verify() + e.close() + } + + + @Test fun get_deleted() { + val e = openStore() + val recid = e.put(1L, LONG) + e.verify() + e.delete(recid, LONG) + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.get(recid, LONG) + } + e.verify() + e.close() + } + + @Test fun update_deleted() { + val e = openStore() + val recid = e.put(1L, LONG) + e.delete(recid, LONG) + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.update(recid, LONG, 2L) + } + e.verify() + e.close() + } + + @Test fun double_delete() { + val e = openStore() + val recid = e.put(1L, LONG) + e.delete(recid, LONG) + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.delete(recid, LONG) + } + e.verify() + e.close() + } + + + @Test fun empty_update_commit() { + if (TT.shortTest()) + return + + var e = openStore() + val recid = e.put("", Serializers.STRING) + assertEquals("", e.get(recid, Serializers.STRING)) + + for (i in 0..9999) { + val s = TT.randomString(80000) + e.update(recid, Serializers.STRING, s) + assertEquals(s, e.get(recid, Serializers.STRING)) + e.commit() + assertEquals(s, e.get(recid, Serializers.STRING)) + } + e.verify() + e.close() + } + + @Test fun delete_reuse() { + for(size in 1 .. 20){ + val e = openStore() + val recid = e.put(TT.randomString(size), Serializers.STRING) + e.delete(recid, Serializers.STRING) + TT.assertFailsWith(DBException.RecordNotFound::class) { + e.get(recid, TT.Serializer_ILLEGAL_ACCESS) + } + + val recid2 = e.put(TT.randomString(size), Serializers.STRING) + assertEquals(recid, recid2) + e.verify() + e.close() + } + } + + +//TODO test +// @Test fun empty_rollback(){ +// val e = openStore() +// if(e is StoreTx) +// e.rollback() +// e.verify() +// e.close() +// } + + @Test fun empty_commit(){ + val e = openStore() + e.commit() + e.verify() + e.close() + } + + @Test fun randomUpdates() { + if(TT.shortTest()) + return; + val s = openStore() + val random = Random(1); + val endTime = TT.nowPlusMinutes(10.0) + val ref = LongObjectHashMap() + //TODO params could cause OOEM if too big. Make another case of tests with extremely large memory, or disk space + val maxRecSize = 1000 + val maxSize = 66000 * 3 + + //fill up + for (i in 0 until maxSize){ + val size = random.nextInt(maxRecSize) + val b = TT.randomByteArray(size, random.nextInt()) + val recid = s.put(b, Serializers.BYTE_ARRAY_NOSIZE) + ref.put(recid, b) + } + s.verify() + + while(endTime>System.currentTimeMillis()){ + ref.forEachKeyValue { recid, record -> + val old = s.get(recid, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(record, old)) + + val size = random.nextInt(maxRecSize) + val b = TT.randomByteArray(size, random.nextInt()) + ref.put(recid,b.clone()) + s.update(recid, Serializers.BYTE_ARRAY_NOSIZE, b) + assertTrue(Arrays.equals(b, s.get(recid, Serializers.BYTE_ARRAY_NOSIZE))); + } + s.verify() + //TODO TX test +// if(s is StoreWAL) { +// s.commit() +// s.verify() +// } + } + } + + @Test fun concurrent_CAS(){ + if(TT.shortTest()) + return; + val s = openStore(); + if(s.isThreadSafe().not()) + return; + + val ntime = TT.nowPlusMinutes(1.0) + var counter = AtomicLong(0); + val recid = s.put(0L, LONG) + TT.fork(10){ + val random = Random(); + while(ntime>System.currentTimeMillis()){ + val plus = random.nextInt(1000).toLong() + val v:Long = s.get(recid, LONG)!! + if(s.compareAndUpdate(recid, LONG, v, v+plus)){ + counter.addAndGet(plus); + } + } + } + + assertTrue(counter.get()>0) + assertEquals(counter.get(), s.get(recid, LONG)) + } + + + @Test fun varRecordSizeCompact(){ + if(TT.shortTest()) + return + val maxStoreSize = 10*1024*1024 + var size = 1 + + while(size + val r = store.get(recid, Serializers.BYTE_ARRAY_NOSIZE) + assertTrue(Arrays.equals(r, TT.randomByteArray(size, seed=i))) + } + } + verify() + store.compact() + verify() + + size += 1 + size/113 + } + } + +// @Test + //TODO reentry test with preprocessor in paranoid mode + fun reentry(){ + val store = openStore() + + val recid = store.put("aa", Serializers.STRING) + val reentrySer1 = object: Serializer { + + override fun serializedType() = String::class.java + + + override fun serialize(out: DataOutput2, k: String) { + out.writeUTF(k) + // that should fail + store.update(recid, Serializers.STRING, k) + } + + override fun deserialize(input: DataInput2): String { + return input.readUTF() + } + } + + val reentrySer2 = object: Serializer { + + override fun serializedType() = String::class.java + + override fun serialize(out: DataOutput2, k: String) { + out.writeUTF(k) + } + + override fun deserialize(input: DataInput2): String { + val s = input.readUTF() + // that should fail + store.update(recid, Serializers.STRING, s) + return s + } + } + + TT.assertFailsWith(DBException.StoreReentry::class){ + store.put("aa", reentrySer1) + store.commit() + } + + val recid2 = store.put("aa", Serializers.STRING) + + TT.assertFailsWith(DBException.StoreReentry::class){ + store.get(recid2, reentrySer2) + } + + TT.assertFailsWith(DBException.StoreReentry::class){ + store.update(recid2, reentrySer1, "bb") + store.commit() + } + + + TT.assertFailsWith(DBException.StoreReentry::class){ + store.compareAndUpdate(recid2, reentrySer1, "aa", "bb") + store.commit() + } + + TT.assertFailsWith(DBException.StoreReentry::class){ + store.compareAndUpdate(recid2, reentrySer2, "aa", "bb") + store.commit() + } + + TT.assertFailsWith(DBException.StoreReentry::class){ + store.compareAndDelete(recid2, reentrySer2, "aa") + store.commit() + } + + } + + + open @Test fun recid_getAll_sorted(){ + val store = openStore() + + val max = 1000 + + val records = (0 until max).map{ n-> + val recid = store.put(n, Serializers.INTEGER) + Pair(recid, n) + } + + val records2 = ArrayList>() + store.getAll{recid, data:ByteArray? -> + data!!.size shouldBe 4 + val n = DataIO.getInt(data!!, 0) + records2+=Pair(recid, n) + } +//TODO check preallocated records are excluded +//TODO check deleted records are excluded + records2.size shouldBe max + for(i in 0 until max){ + val (recid, n) = records2[i] + n shouldBe i + store.get(recid, Serializers.INTEGER) shouldBe i + + records[i].first shouldBe recid + records[i].second shouldBe n + } + } +// +// @Test fun export_to_archive(){ +// val store = openStore() +// +// val max = 1000 +// +// val records = (0 until max).map{ n-> +// val recid = store.put(n*1000, Serializers.INTEGER) +// Pair(recid, n*1000) +// } +// +// val out = ByteArrayOutputStream() +// StoreArchive.importFromStore(store, out) +// +// val archive = StoreArchive(ByteBuffer.wrap(out.toByteArray())) +// +// for((recid,n) in records){ +// archive.get(recid, Serializers.INTEGER) shouldBe n +// } +// } + + @Test fun empty(){ + val store = openStore() + store.isEmpty() shouldBe true + val recid = store.put(1, Serializers.INTEGER) + store.isEmpty() shouldBe false + + store.delete(recid, Serializers.INTEGER) + //TODO restore empty state when no data in store? perhaps not possible, so replace is 'isFresh()` (no data inserted yet) +// store.isEmpty() shouldBe true + } + + @Test fun null_prealloc_update_delete(){ + val store = openStore() + val recid = store.preallocate() + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + store.update(recid, LONG, 1L) + } + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + store.get(recid, TT.Serializer_ILLEGAL_ACCESS) + } + TT.assertFailsWith(DBException.PreallocRecordAccess::class) { + store.delete(recid, TT.Serializer_ILLEGAL_ACCESS) + } + store.preallocatePut(recid, LONG, 1L) + store.delete(recid, LONG); + + TT.assertFailsWith(DBException.RecordNotFound::class) { + store.get(recid, TT.Serializer_ILLEGAL_ACCESS) + } + } + + //TODO nullability tests outside of kotlin + +} +