├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── build.gradle ├── buildSrc ├── build.gradle └── src │ └── main │ └── java │ ├── GenMarkers.kt │ ├── GenRecords.kt │ └── MDBCodeGen.kt ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── logger.properties └── src ├── assembly ├── bin-component.xml └── bin.xml ├── main └── java │ └── org │ └── mapdb │ ├── CC.java │ ├── DBException.java │ ├── cli │ ├── Export.java │ └── Import.java │ ├── db │ └── DB.java │ ├── flat │ └── LongBufStack.java │ ├── io │ ├── DataIO.java │ ├── DataInput2.java │ ├── DataInput2ByteArray.java │ ├── DataInput2ByteBuffer.java │ ├── DataInputToStream.java │ ├── DataOutput2.java │ └── DataOutput2ByteArray.java │ ├── list │ ├── KernelList.java │ └── MonolithList.java │ ├── record │ └── Atomic.java │ ├── ser │ ├── ArrayDeltaSerializer.java │ ├── ArrayListSerializer.java │ ├── ArraySerializer.java │ ├── ArrayTupleSerializer.java │ ├── BigDecimalSerializer.java │ ├── BigIntegerSerializer.java │ ├── BooleanSerializer.java │ ├── ByteArrayDelta2Serializer.java │ ├── ByteArrayDeltaSerializer.java │ ├── ByteArrayNoSizeSerializer.java │ ├── ByteArraySerializer.java │ ├── ByteSerializer.java │ ├── CharArraySerializer.java │ ├── CharSerializer.java │ ├── ClassSerializer.java │ ├── DateSerializer.java │ ├── DefaultGroupSerializer.java │ ├── DoubleArraySerializer.java │ ├── DoubleSerializer.java │ ├── EightByteSerializer.java │ ├── FloatArraySerializer.java │ ├── FloatSerializer.java │ ├── FourByteSerializer.java │ ├── GroupSerializer.java │ ├── IntArraySerializer.java │ ├── IntegerDeltaSerializer.java │ ├── IntegerPackedSerializer.java │ ├── IntegerSerializer.java │ ├── JavaSerializer.java │ ├── LongArraySerializer.java │ ├── LongDeltaSerializer.java │ ├── LongPackedSerializer.java │ ├── LongSerializer.java │ ├── RecidArraySerializer.java │ ├── RecidSerializer.java │ ├── Serializer.java │ ├── SerializerIllegalAccess.java │ ├── SerializerUtils.java │ ├── Serializers.java │ ├── ShortArraySerializer.java │ ├── ShortSerializer.java │ ├── StringAsciiSerializer.java │ ├── StringDelta2Serializer.java │ ├── StringDeltaSerializer.java │ ├── StringInternSerializer.java │ ├── StringNoSizeSerializer.java │ ├── StringOrigHashSerializer.java │ ├── StringSerializer.java │ └── UUIDSerializer.java │ ├── store │ ├── ConcMapStore.java │ ├── FileHeapBufStore.java │ ├── HeapBufStore.java │ ├── ReadonlyStore.java │ ├── Recids.java │ ├── Store.java │ ├── StoreTx.java │ ├── legacy │ │ ├── DataInput2Exposed.java │ │ ├── Fun.java │ │ ├── LongConcurrentHashMap.java │ │ ├── LongHashMap.java │ │ ├── LongMap.java │ │ ├── Store2.java │ │ ├── StoreDirect.java │ │ └── Volume.java │ └── li │ │ ├── LiStore.java │ │ └── LiUtil.java │ └── util │ ├── Exporter.java │ ├── IO.java │ ├── JavaUtils.java │ └── MonoRef.java └── test └── java ├── aaGenTest.kt ├── harmony ├── AbstractListTest.java ├── ArrayListTest.java ├── LinkedListTest.java ├── Support_CollectionTest.java ├── Support_ListTest.java └── Support_UnmodifiableCollectionTest.java └── org └── mapdb ├── DBCollectionTest.kt ├── TT.kt ├── Verifiable.java ├── flat └── LongBufStackTest.kt ├── guavaTests ├── ConcurrentMapInterfaceTest.java ├── GwtCompatible.java ├── Helpers.java ├── MapInterfaceTest.java └── SortedMapInterfaceTest.java ├── io └── DataIOTest.java ├── jsr166Tests ├── BlockingQueueTest.java ├── Collection8Test.java ├── CollectionImplementation.java ├── CollectionTest.java ├── JSR166TestCase.java ├── LinkedBlockingDeque8Test.java ├── LinkedBlockingDequeTest.java ├── LinkedBlockingQueue8Test.java ├── LinkedBlockingQueueTest.java └── TreeMapTest.java ├── kotlin ├── Issue888_JavaI.java ├── Issue888_KotlinI.kt └── Issue888_serializer_override.java ├── list ├── KernelListHarmonyTest.java └── MonolithListHarmonyTest.java ├── record ├── BooleanRecordTest.java ├── IntRecordTest.java ├── LongRecordTest.java ├── StringRecordTest.java └── VarRecordTest.java ├── ser ├── BTreeKeySerializerTest.java ├── SerializerArrayTest.java ├── SerializerTest.kt ├── SerializersJavaAccessTest.java └── SerializersTest.kt └── store ├── StoreReopenTest.kt └── StoreTest.kt /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: jankotek 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Java CI 3 | 4 | on: [push] 5 | 6 | jobs: 7 | test: 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [ubuntu-18.04, macOS-latest, windows-2016] 12 | java: [8, 11] 13 | fail-fast: false 14 | max-parallel: 4 15 | name: Test JDK ${{ matrix.java }}, ${{ matrix.os }} 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up JDK 20 | uses: actions/setup-java@v1 21 | with: 22 | java-version: ${{ matrix.java }} 23 | - name: Grant execute permission for gradlew 24 | run: chmod +x gradlew 25 | - name: Test with Gradle 26 | run: ./gradlew test 27 | ... -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings 4 | .idea 5 | target 6 | build 7 | bin 8 | out 9 | helper 10 | *.iml 11 | *.ipr 12 | *.iws 13 | .directory 14 | *.log 15 | .gradle 16 | *.log 17 | 18 | 19 | srcGen/* -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - openjdk8 5 | - openjdk11 6 | # - oraclejdk10 7 | 8 | sudo: false 9 | 10 | before_cache: 11 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 12 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 13 | 14 | #before_install: 15 | # - sudo apt-get purge gradle 16 | # - sudo add-apt-repository ppa:cwchien/gradle -y 17 | # - sudo apt-get update -q 18 | # - sudo apt-get install gradle -y 19 | 20 | cache: 21 | directories: 22 | - $HOME/.gradle/caches/ 23 | - $HOME/.gradle/wrapper/ 24 | - $HOME/.m2/repository/ 25 | 26 | install: /bin/true 27 | 28 | script: ./gradlew test 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | MapDB: database engine 4 | ======================= 5 | [![Build Status](https://travis-ci.org/jankotek/mapdb.svg?branch=master)](https://travis-ci.org/jankotek/mapdb) 6 | [![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) 7 | [![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) 8 | 9 | 10 | MapDB combines embedded database engine and Java collections. 11 | It is free under Apache 2 license. MapDB is flexible and can be used in many roles: 12 | 13 | * Drop-in replacement for Maps, Lists, Queues and other collections. 14 | * Off-heap collections not affected by Garbage Collector 15 | * Multilevel cache with expiration and disk overflow. 16 | * RDBMs replacement with transactions, MVCC, incremental backups etc… 17 | * Local data processing and filtering. MapDB has utilities to process huge quantities of data in reasonable time. 18 | 19 | Hello world 20 | ------------------- 21 | 22 | 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) 23 | 24 | ```xml 25 | 26 | org.mapdb 27 | mapdb 28 | VERSION 29 | 30 | ``` 31 | 32 | Hello world: 33 | 34 | ```java 35 | //import org.mapdb.* 36 | DB db = DBMaker.memoryDB().make(); 37 | ConcurrentMap map = db.hashMap("map").make(); 38 | map.put("something", "here"); 39 | ``` 40 | 41 | You can continue with [quick start](https://jankotek.gitbooks.io/mapdb/content/quick-start/) or refer to the [documentation](https://jankotek.gitbooks.io/mapdb/). 42 | 43 | Support 44 | ------------ 45 | 46 | More [details](http://www.mapdb.org/support/). 47 | 48 | Development 49 | -------------------- 50 | 51 | MapDB is written in Kotlin, you will need IntelliJ Idea. 52 | 53 | You can use Gradle to build MapDB. 54 | 55 | MapDB is extensively unit-tested. 56 | By default, only tiny fraction of all tests are executed, so build finishes under 10 minutes. 57 | Full test suite has over million test cases and runs for several hours/days. 58 | To run full test suite, set `-Dmdbtest=1` VM option. 59 | 60 | Longer unit tests might require more memory. Use this to increase heap memory assigned to unit tests: `-DtestArgLine="-Xmx3G"` 61 | 62 | By default unit tests are executed in 3 threads. Thread count is controlled by `-DtestThreadCount=3` property 63 | 64 | On machine with limited memory you can change fork mode so unit test consume less RAM, but run longer: `-DtestReuseForks=false` -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | 3 | ext.kotlin_version = '1.4.10' 4 | ext.junit_version = '5.7.0' 5 | ext.ec_version = '10.4.0' 6 | ext.guava_version = '28.2-jre' 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | apply plugin: "kotlin" 17 | 18 | compileKotlin { 19 | kotlinOptions { 20 | jvmTarget = '1.8' 21 | } 22 | } 23 | 24 | 25 | sourceSets { 26 | //combine Kotlin and Java source into same dirs 27 | main.kotlin.srcDirs += 'src/main/java' 28 | main.java.srcDirs += 'src/main/java' 29 | test.kotlin.srcDirs += 'src/test/java' 30 | test.java.srcDirs += 'src/test/java' 31 | 32 | //include generated code into build 33 | main.kotlin.srcDirs += 'srcGen/main/java' 34 | main.java.srcDirs += 'srcGen/main/java' 35 | test.kotlin.srcDirs += 'srcGen/test/java' 36 | test.java.srcDirs += 'srcGen/test/java' 37 | 38 | } 39 | 40 | repositories { 41 | mavenCentral() 42 | } 43 | 44 | 45 | test{ 46 | maxParallelForks = 5 47 | maxHeapSize = '2G' 48 | } 49 | 50 | dependencies { 51 | compile "org.eclipse.collections:eclipse-collections-api:$ec_version" 52 | compile "org.eclipse.collections:eclipse-collections:$ec_version" 53 | 54 | compile "com.google.guava:guava:$guava_version" 55 | 56 | compile group: 'org.jetbrains', name: 'annotations', version: '20.1.0' 57 | 58 | compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 59 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 60 | 61 | compile 'org.lz4:lz4-java:1.7.1' 62 | 63 | testCompile("io.kotlintest:kotlintest-runner-junit5:3.4.2") 64 | testCompile("org.junit.vintage:junit-vintage-engine:$junit_version") 65 | testCompile("org.junit.jupiter:junit-jupiter-api:$junit_version") 66 | testCompile("org.junit.jupiter:junit-jupiter-engine:$junit_version") 67 | } 68 | -------------------------------------------------------------------------------- /buildSrc/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.2.50' 3 | 4 | repositories { 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 10 | } 11 | } 12 | 13 | apply plugin: "kotlin" 14 | 15 | compileKotlin { 16 | kotlinOptions { 17 | // freeCompilerArgs = ['-Xenable-jvm-default'] 18 | jvmTarget = '1.8' 19 | } 20 | } 21 | 22 | 23 | sourceSets { 24 | main.kotlin.srcDirs += 'src/main/java' 25 | main.java.srcDirs += 'src/main/java' 26 | test.kotlin.srcDirs += 'src/test/java' 27 | test.java.srcDirs += 'src/test/java' 28 | 29 | 30 | } 31 | 32 | repositories { 33 | mavenCentral() 34 | } 35 | 36 | 37 | dependencies { 38 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 39 | } 40 | 41 | 42 | task codegenClean(type: Delete) { 43 | delete "../srcGen" 44 | } 45 | 46 | task codegen(type:JavaExec) { 47 | 48 | dependsOn(codegenClean) 49 | main = "MDBCodeGen" 50 | classpath = sourceSets.main.runtimeClasspath 51 | } 52 | 53 | 54 | build.dependsOn(codegen) -------------------------------------------------------------------------------- /buildSrc/src/main/java/GenMarkers.kt: -------------------------------------------------------------------------------- 1 | import java.io.File 2 | 3 | object GenMarkers{ 4 | 5 | val markers:Map = linkedMapOf( 6 | Pair("//-WLOCK", """lock.writeLock().lock(); try{"""), 7 | Pair("//-WUNLOCK", """}finally{lock.writeLock().unlock();}"""), 8 | Pair("//-newRWLOCK", """java.util.concurrent.locks.ReadWriteLock lock = new java.util.concurrent.locks.ReentrantReadWriteLock();""") 9 | ) 10 | 11 | fun recurJavaFiles(dir:File, f: (File) -> Unit){ 12 | val allFiles = dir.listFiles(); 13 | allFiles.filter { it.extension.equals("java") }.forEach(f) 14 | allFiles.filter{it.isDirectory}.forEach{recurJavaFiles(it,f)} 15 | } 16 | 17 | 18 | // process //*-WLOCk markers 19 | fun wlock(srcDir: File, genDir:File) { 20 | recurJavaFiles(srcDir) { f:File-> 21 | var content = f.readText() 22 | 23 | if(markers.keys.none{content.contains(it)}) { 24 | return@recurJavaFiles 25 | } 26 | for ((marker, repl) in markers) { 27 | content = content.replace(marker, repl) 28 | } 29 | 30 | val oldClassName = f.nameWithoutExtension 31 | content = content.replace("class "+oldClassName, "class ${oldClassName}RWLock") 32 | content = content.replace(" "+oldClassName+"(", " ${oldClassName}RWLock(") 33 | 34 | val newFile = File(genDir.path + "/"+ f.relativeTo(srcDir).parent +"/"+ oldClassName + "RWLock.java") 35 | 36 | newFile.parentFile.mkdirs() 37 | newFile.writeText(content) 38 | 39 | } 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /buildSrc/src/main/java/MDBCodeGen.kt: -------------------------------------------------------------------------------- 1 | import org.gradle.internal.impldep.org.apache.commons.io.FileUtils 2 | import java.io.File 3 | 4 | class MDBCodeGen{ 5 | companion object { 6 | @JvmStatic 7 | fun main(args: Array) { 8 | 9 | val srcGenDir = File("../srcGen/main/java") 10 | val srcDir = File("../src/main/java") 11 | 12 | val testGenDir = File("../srcGen/test/java") 13 | 14 | 15 | FileUtils.write(File(srcGenDir, "AACodeGen.java"), """ 16 | public class AACodeGen{ 17 | } 18 | """) 19 | 20 | val srcDirRecords = File(srcGenDir, "org/mapdb/record/") 21 | srcDirRecords.mkdirs() 22 | GenRecords.makeRecordMakers(srcDirRecords) 23 | 24 | GenMarkers.wlock(srcDir, srcGenDir); 25 | 26 | } 27 | } 28 | 29 | 30 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jankotek/mapdb/8721c0e824d8d546ecc76639c05ccbc618279511/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem http://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /logger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # An example of logger config file used for debugging. 3 | # 4 | # MapDB is compiled without logging messages by default. 5 | # Make sure you enable them in CC.java 6 | # 7 | # You must enable this file by passing system property before JVM starts 8 | # 9 | # >java -Djava.util.logging.config.file=logger.properties 10 | # 11 | 12 | handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler 13 | 14 | # Default global logging level. 15 | # Loggers and Handlers may override this level 16 | .level=FINEST 17 | 18 | # Loggers 19 | # ------------------------------------------ 20 | # Loggers are usually attached to packages. 21 | # Here, the level for each package is specified. 22 | # The global level is used by default, so levels 23 | # specified here simply act as an override. 24 | org.mapdb.level=ALL 25 | 26 | #some other filtering options 27 | myapp.business.level=CONFIG 28 | myapp.data.level=SEVERE 29 | 30 | # Handlers 31 | java.util.logging.ConsoleHandler.level=ALL 32 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 33 | 34 | # --- FileHandler --- 35 | java.util.logging.FileHandler.level=ALL 36 | 37 | # Naming style for the output file: 38 | # (The output file is placed in the directory 39 | # defined by the "user.home" System property.) 40 | java.util.logging.FileHandler.pattern=%h/java%u.log 41 | 42 | # Limiting size of output file in bytes: 43 | java.util.logging.FileHandler.limit=500000 44 | 45 | # Number of output files to cycle through, by appending an 46 | # integer to the base file name: 47 | java.util.logging.FileHandler.count=1 48 | 49 | # Style of output (Simple or XML): 50 | java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter -------------------------------------------------------------------------------- /src/assembly/bin-component.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | lib 5 | false 6 | runtime 7 | 8 | 9 | 10 | 20 | 21 | -------------------------------------------------------------------------------- /src/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 5 | bin 6 | 7 | zip 8 | 9 | 10 | src/assembly/bin-component.xml 11 | 12 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/CC.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | //TODO name conflict with 3.0, remove this class 4 | public interface CC { 5 | boolean PARANOID = false; 6 | boolean ASSERT = true; 7 | //TODO move to preprocessor 8 | boolean LOG_STORE = false; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/DBException.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | public class DBException extends RuntimeException { 5 | 6 | public DBException(Exception cause){ 7 | super(cause); 8 | } 9 | 10 | public DBException(String msg){ 11 | super(msg); 12 | } 13 | 14 | public DBException(String msg, Exception cause){ 15 | super(msg,cause); 16 | } 17 | 18 | public static class RecordNotFound extends DBException{ 19 | public RecordNotFound(){ 20 | super("record not found"); 21 | } 22 | } 23 | 24 | 25 | 26 | public static class StoreReentry extends DBException { 27 | public StoreReentry() { 28 | super("repeated call to Store method"); 29 | } 30 | } 31 | 32 | public static class FileLocked extends DBException { 33 | public FileLocked() { 34 | super("file locked"); 35 | } 36 | } 37 | 38 | public static class PreallocRecordAccess extends DBException{ 39 | public PreallocRecordAccess(){ 40 | super("preallocated record accessed"); 41 | } 42 | } 43 | 44 | public static class StoreClosed extends DBException{ 45 | public StoreClosed(){ 46 | super("store closed"); 47 | } 48 | } 49 | 50 | 51 | public static class DataCorruption extends DBException{ 52 | public DataCorruption(){ 53 | super("data corruption"); 54 | } 55 | 56 | public DataCorruption(String msg) { 57 | super(msg); 58 | } 59 | } 60 | 61 | public static class SerializationError extends DBException{ 62 | public SerializationError(Exception e){ 63 | super(e); 64 | } 65 | } 66 | 67 | public static class WrongConfig extends DBException { 68 | 69 | public WrongConfig(String msg) { 70 | super(msg); 71 | } 72 | } 73 | 74 | public static class WrongSerializer extends WrongConfig{ 75 | public WrongSerializer(){ 76 | super("wrong serializer used"); 77 | } 78 | } 79 | 80 | 81 | public static class PointerChecksumBroken extends DataCorruption{ 82 | 83 | } 84 | 85 | public static class TODO extends DBException{ 86 | 87 | public TODO() { 88 | super("not implemented yet"); 89 | } 90 | 91 | public TODO(String msg) { 92 | super(msg); 93 | } 94 | } 95 | 96 | public static class RecordNotPreallocated extends DBException { 97 | 98 | public RecordNotPreallocated() { 99 | super("Record was not preallocated"); 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /src/main/java/org/mapdb/cli/Export.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.cli; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | public class Export { 6 | 7 | public static void main(@NotNull String[] arrayOf) { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/cli/Import.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.cli; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | public class Import { 6 | 7 | public static void main(@NotNull String[] args) { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/db/DB.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.db; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.mapdb.store.HeapBufStore; 5 | import org.mapdb.store.Store; 6 | 7 | import java.io.File; 8 | 9 | public class DB { 10 | private final Store store; 11 | 12 | public DB(Store store) { 13 | this.store = store; 14 | } 15 | 16 | public Store getStore(){ 17 | return store; 18 | } 19 | 20 | public void close() { 21 | 22 | } 23 | 24 | public static class Maker { 25 | 26 | private final Store store; 27 | 28 | private Maker(Store store) { 29 | this.store = store; 30 | } 31 | 32 | @NotNull 33 | public static Maker appendFile(@NotNull File f) { 34 | return null; 35 | } 36 | 37 | @NotNull 38 | public DB make() { 39 | return new DB(store); 40 | } 41 | 42 | @NotNull 43 | public static Maker heapSer() { 44 | return new Maker(new HeapBufStore()); 45 | } 46 | 47 | @NotNull 48 | public static Maker memoryDB() { 49 | return new Maker(new HeapBufStore()); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/flat/LongBufStack.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.flat; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | public class LongBufStack{ 6 | 7 | private int pos = 0; 8 | 9 | 10 | //TODO LongBuffer? 11 | private final ByteBuffer buf; 12 | 13 | public LongBufStack(ByteBuffer buf) { 14 | this.buf = buf; 15 | } 16 | 17 | public LongBufStack(){ 18 | this(ByteBuffer.allocate(8*1024*1024)); 19 | } 20 | 21 | public long pop(){ 22 | if(pos==0) 23 | return 0L; 24 | return buf.getLong(8*(--pos)); 25 | } 26 | 27 | public void push(long value){ 28 | if(value == 0L) 29 | throw new IllegalArgumentException(); 30 | 31 | buf.putLong(8*(pos++), value); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/io/DataInput2.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.io; 2 | 3 | import java.io.DataInput; 4 | import java.io.IOException; 5 | 6 | public interface DataInput2{ 7 | 8 | /** 9 | * How many bytes are available for read (`total size - current position`). 10 | * Returns `Integer.MIN_VALUE` if this information is not available 11 | */ 12 | int available() ; 13 | 14 | 15 | /** returns true if more bytes are available for read 16 | * 17 | * TODO throws exception if output has no EOF info? 18 | */ 19 | boolean availableMore()throws IOException; 20 | 21 | 22 | int readPackedInt() ; 23 | 24 | long readPackedLong() ; 25 | 26 | default long readPackedRecid(){ 27 | //TODO bit parity for recids 28 | return readPackedLong(); 29 | } 30 | 31 | default long readRecid(){ 32 | //TODO bit parity for recids 33 | return readLong(); 34 | } 35 | 36 | long readLong(); 37 | 38 | default float readFloat() { 39 | return java.lang.Float.intBitsToFloat(readInt()); 40 | } 41 | 42 | int readInt(); 43 | 44 | default double readDouble() { 45 | return java.lang.Double.longBitsToDouble(readLong()); 46 | } 47 | 48 | default String readLine() { 49 | return readUTF(); 50 | } 51 | 52 | default String readUTF() { 53 | //TODO is it better then DataOutputStream.readUTF? 54 | int len = readPackedInt(); 55 | char[] b = new char[len]; 56 | for (int i=0;i0; 102 | } 103 | 104 | @Override 105 | public int readPackedInt() { 106 | return readInt(); 107 | } 108 | 109 | @Override 110 | public long readPackedLong() { 111 | return readLong(); 112 | } 113 | 114 | 115 | @Override 116 | public void unpackLongSkip(int count) { 117 | byte[] b = buf; 118 | int pos2 = this.pos; 119 | while(count>0){ 120 | // count -= (b[pos2++]&0x80)>>7; 121 | //TODO go back to packed longs, remove code bellow 122 | readLong(); 123 | count--; 124 | pos2+=8; 125 | } 126 | this.pos = pos2; 127 | } 128 | 129 | } 130 | 131 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/io/DataInput2ByteBuffer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.io; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | /** DataInput on top of {@link ByteBuffer} */ 6 | public final class DataInput2ByteBuffer implements DataInput2 { 7 | 8 | protected final ByteBuffer buf; 9 | 10 | public DataInput2ByteBuffer(ByteBuffer buf) { 11 | this.buf = buf; 12 | } 13 | 14 | public void readFully(byte[] b, int off, int len) { 15 | buf.get(b, off,len); 16 | } 17 | 18 | @Override 19 | public int skipBytes(final int n) { 20 | buf.position(buf.position()+n); 21 | return n; 22 | } 23 | 24 | @Override 25 | public boolean readBoolean() { 26 | return buf.get() == 1; 27 | } 28 | 29 | @Override 30 | public byte readByte() { 31 | return buf.get(); 32 | } 33 | 34 | @Override 35 | public int readUnsignedByte() { 36 | return buf.get() & 0xff; 37 | } 38 | 39 | @Override 40 | public short readShort() { 41 | return buf.getShort(); 42 | } 43 | 44 | @Override 45 | public char readChar() { 46 | return buf.getChar(); 47 | } 48 | 49 | @Override 50 | public int readInt() { 51 | return buf.getInt(); 52 | } 53 | 54 | @Override 55 | public long readLong() { 56 | return buf.getLong(); 57 | } 58 | 59 | 60 | @Override 61 | public int available() { 62 | return buf.remaining(); 63 | } 64 | 65 | @Override 66 | public boolean availableMore() { 67 | return available()>0; 68 | } 69 | 70 | @Override 71 | public int readPackedInt() { 72 | return readInt(); 73 | } 74 | 75 | @Override 76 | public long readPackedLong() { 77 | return readLong(); 78 | } 79 | 80 | 81 | @Override 82 | public void unpackLongSkip(int count) { 83 | while(count>0){ 84 | //TODO go back to packed longs, remove code bellow 85 | readLong(); 86 | count--; 87 | } 88 | } 89 | 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/io/DataInputToStream.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.io; 2 | 3 | import java.io.Closeable; 4 | import java.io.DataInput; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | 8 | /** 9 | * Wraps {@code DataInput} into {@code InputStream} 10 | */ 11 | public final class DataInputToStream extends InputStream { 12 | 13 | protected final DataInput2 in; 14 | 15 | public DataInputToStream(DataInput2 in) { 16 | this.in = in; 17 | } 18 | 19 | @Override 20 | public int read(byte[] b, int off, int len) throws IOException { 21 | in.readFully(b,off,len); 22 | return len; 23 | } 24 | 25 | @Override 26 | public long skip(long n) throws IOException { 27 | n = Math.min(n, Integer.MAX_VALUE); 28 | //$DELAY$ 29 | return in.skipBytes((int) n); 30 | } 31 | 32 | @Override 33 | public void close() throws IOException { 34 | if(in instanceof Closeable) 35 | ((Closeable) in).close(); 36 | } 37 | 38 | @Override 39 | public int read() throws IOException { 40 | return in.readUnsignedByte(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/io/DataOutput2.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.io; 2 | 3 | import java.io.DataOutput; 4 | import java.io.IOException; 5 | 6 | 7 | public interface DataOutput2{ 8 | 9 | /** 10 | * Give a hint to DataOutput about total size of serialized data. 11 | * This may prevent `byte[]` resize. And huge records might be placed into temporary file 12 | */ 13 | void sizeHint(int size); 14 | 15 | /** write int in packed form */ 16 | void writePackedInt(int value); 17 | 18 | /** write long in packed form */ 19 | void writePackedLong(long value); 20 | 21 | /** write recid, recids have extra parity bit to detect data corruption */ 22 | void writeRecid(long recid); 23 | 24 | /** write recid in packed form, recids have extra parity bit to detect data corruption */ 25 | void writePackedRecid(long recid); 26 | 27 | /** copy content of this DataOutput2 into `ByteArray` */ 28 | byte[] copyBytes(); 29 | 30 | 31 | void writeBoolean(boolean v); 32 | 33 | void writeByte(int v); 34 | 35 | void writeShort(int v); 36 | 37 | void writeChar(int v); 38 | 39 | void writeInt(int v); 40 | 41 | void writeLong(long v); 42 | 43 | void writeFloat(float v); 44 | 45 | void writeDouble(double v); 46 | 47 | void writeBytes(String s); 48 | 49 | void writeChars(String s); 50 | 51 | void writeUTF(String s); 52 | 53 | @Deprecated //TODO temp method for compatibility 54 | default void packInt(int i){ 55 | writePackedInt(i); 56 | } 57 | 58 | void write(int bytee); //TODO remove this method? compatibility with java.io.DataOutput 59 | 60 | void write(byte[] buf); 61 | void write(byte b[], int off, int len); 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/list/KernelList.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.list; 2 | 3 | import org.mapdb.ser.Serializer; 4 | import org.mapdb.ser.Serializers; 5 | import org.mapdb.store.Store; 6 | 7 | import java.util.*; 8 | 9 | public class KernelList 10 | extends AbstractList 11 | implements List, RandomAccess { 12 | 13 | private static final Serializer KERNEL_SER = Serializers.LONG_ARRAY; 14 | 15 | private final Store kernelStore; 16 | private final Store entryStore; 17 | private final long recid; 18 | private final Serializer ser; 19 | 20 | public KernelList(Store kernelStore, Store entryStore, long recid, Serializer ser) { 21 | this.kernelStore = kernelStore; 22 | this.entryStore = entryStore; 23 | this.recid = recid; 24 | this.ser = ser; 25 | } 26 | 27 | 28 | public static class Maker { 29 | private final Store store; 30 | 31 | private Store entryStore = null; 32 | private final Serializer ser; 33 | private final long recid; 34 | 35 | public Maker(Store store, long recid, Serializer ser) { 36 | this.store = store; 37 | this.entryStore = store; 38 | this.recid = recid; 39 | this.ser = ser; 40 | } 41 | 42 | public static KernelList.Maker newList(Store store, Serializer ser) { 43 | long recid = store.put(new long[]{}, KERNEL_SER); 44 | return new KernelList.Maker(store, recid, ser); 45 | } 46 | 47 | public Maker entryStore(Store store){ 48 | this.entryStore = store; 49 | return this; 50 | } 51 | 52 | public KernelList make(){ 53 | return new KernelList(store, entryStore, recid, ser); 54 | } 55 | } 56 | 57 | 58 | @Override 59 | public E get(int index) { 60 | long entryRecid = getKernel()[index]; 61 | return entryStore.get(entryRecid, ser); 62 | } 63 | 64 | @Override 65 | public int size() { 66 | return getKernel().length; 67 | } 68 | 69 | @Override 70 | public boolean add(E e) { 71 | long[] kernel = getKernel(); 72 | kernel = Arrays.copyOf(kernel, kernel.length+1); 73 | long newRecid = entryStore.put(e, ser); 74 | kernel[kernel.length-1] = newRecid; 75 | storeKernel(kernel); 76 | return true; 77 | } 78 | 79 | @Override 80 | public void add(int index, E e) { 81 | long[] kernel = getKernel(); 82 | if(index<0 || index>kernel.length) 83 | throw new IndexOutOfBoundsException(); 84 | 85 | long[] kernel2 = Arrays.copyOf(kernel, kernel.length+1); 86 | System.arraycopy(kernel, index, kernel2, index+1, kernel.length-index); 87 | 88 | long newRecid = entryStore.put(e, ser); 89 | kernel2[index] = newRecid; 90 | storeKernel(kernel2); 91 | } 92 | 93 | @Override 94 | public boolean addAll(Collection c) { 95 | long[] kernel = getKernel(); 96 | int pos = kernel.length; 97 | kernel = Arrays.copyOf(kernel, kernel.length+c.size()); 98 | for(E e:c){ 99 | long newRecid = entryStore.put(e, ser); 100 | kernel[pos++] = newRecid; 101 | } 102 | if(pos!=kernel.length) 103 | throw new ConcurrentModificationException(); 104 | storeKernel(kernel); 105 | return true; 106 | } 107 | 108 | @Override 109 | public boolean addAll(int index, Collection c) { 110 | long[] kernel = getKernel(); 111 | if(index<0 || index>kernel.length) 112 | throw new IndexOutOfBoundsException(); 113 | int csize = c.size(); 114 | long[] kernel2 = Arrays.copyOf(kernel, kernel.length+csize); 115 | System.arraycopy(kernel, index, kernel2, index+csize, kernel.length-index); 116 | kernel=null; //release memory for GC 117 | int pos = index; 118 | for(E e:c){ 119 | long newRecid = entryStore.put(e, ser); 120 | kernel2[pos++] = newRecid; 121 | } 122 | if(pos!=csize+index) 123 | throw new ConcurrentModificationException(); 124 | storeKernel(kernel2); 125 | return true; 126 | } 127 | 128 | @Override 129 | public E remove(int index) { 130 | long[] kernel = getKernel(); 131 | long eRecid = kernel[index]; 132 | E ret = entryStore.getAndDelete(eRecid, ser); 133 | long[] kernel2 = Arrays.copyOf(kernel, kernel.length-1); 134 | System.arraycopy(kernel, index+1, kernel2, index, kernel2.length-index); 135 | storeKernel(kernel2); 136 | return ret; 137 | } 138 | 139 | @Override 140 | public E set(int index, E element) { 141 | long[] kernel = getKernel(); 142 | return entryStore.getAndUpdate(kernel[index], ser, element); 143 | } 144 | 145 | protected void storeKernel(long[] kernel) { 146 | for(long recid:kernel) { 147 | if (recid <= 0) 148 | throw new ConcurrentModificationException(); 149 | } 150 | kernelStore.update(recid, KERNEL_SER, kernel); 151 | } 152 | 153 | protected long[] getKernel(){ 154 | return kernelStore.get(recid, KERNEL_SER); 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/list/MonolithList.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.list; 2 | 3 | import org.mapdb.ser.ArrayListSerializer; 4 | import org.mapdb.ser.Serializer; 5 | import org.mapdb.store.Store; 6 | 7 | import java.util.*; 8 | 9 | public class MonolithList 10 | extends AbstractList 11 | implements List, RandomAccess { 12 | 13 | public static class Maker { 14 | private final Store store; 15 | private final Serializer ser; 16 | private final long recid; 17 | 18 | public Maker(Store store, long recid, Serializer ser) { 19 | this.store = store; 20 | this.recid = recid; 21 | this.ser = ser; 22 | } 23 | 24 | public static Maker newList(Store store, Serializer ser) { 25 | long recid = store.put(new ArrayList(), new ArrayListSerializer(ser)); 26 | return new Maker(store, recid, ser); 27 | } 28 | 29 | public MonolithList make(){ 30 | return new MonolithList(store, recid, ser); 31 | } 32 | } 33 | 34 | 35 | private final Store store; 36 | private final long recid; 37 | private final Serializer ser; 38 | private final Serializer> listSer; 39 | 40 | public MonolithList(Store store, long recid, Serializer ser) { 41 | this.store = store; 42 | this.recid = recid; 43 | this.ser = ser; 44 | this.listSer = new ArrayListSerializer(ser); 45 | } 46 | 47 | 48 | @Override 49 | public E get(int index) { 50 | ArrayList list = store.get(recid, listSer); 51 | return list.get(index); 52 | } 53 | 54 | @Override 55 | public int size() { 56 | ArrayList list = store.get(recid, listSer); 57 | return list.size(); 58 | } 59 | 60 | @Override 61 | public boolean add(E e) { 62 | ArrayList list = getClone(); 63 | list.add(e); 64 | store(list); 65 | return true; 66 | } 67 | 68 | @Override 69 | public E set(int index, E element) { 70 | ArrayList list = getClone(); 71 | E e=list.set(index,element); 72 | store(list); 73 | return e; 74 | } 75 | 76 | @Override 77 | public void add(int index, E element) { 78 | ArrayList list = getClone(); 79 | list.add(index,element); 80 | store(list); 81 | } 82 | 83 | @Override 84 | public boolean addAll(int index, Collection c) { 85 | ArrayList list = getClone(); 86 | list.addAll(index, c); 87 | store(list); 88 | return true; 89 | } 90 | 91 | @Override 92 | public boolean addAll(Collection c) { 93 | ArrayList list = getClone(); 94 | list.addAll(c); 95 | store(list); 96 | return true; 97 | } 98 | 99 | @Override 100 | public E remove(int index) { 101 | ArrayList list = getClone(); 102 | E e=list.remove(index); 103 | store(list); 104 | return e; 105 | } 106 | 107 | protected ArrayList getClone() { 108 | return (ArrayList) store.get(recid, listSer).clone(); 109 | } 110 | 111 | protected void store(ArrayList list) { 112 | store.update(recid, listSer, list); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/ArrayDeltaSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.io.DataInput2; 4 | import org.mapdb.io.DataOutput2; 5 | 6 | import java.io.IOException; 7 | 8 | /** 9 | * Created by jan on 2/28/16. 10 | */ 11 | public class ArrayDeltaSerializer extends ArraySerializer { 12 | 13 | private static final long serialVersionUID = -930920902390439234L; 14 | 15 | 16 | public ArrayDeltaSerializer(Serializer serializer) { 17 | super(serializer); 18 | } 19 | 20 | @Override 21 | public void valueArraySerialize(DataOutput2 out, Object[] vals2) { 22 | Object[] vals = (Object[]) vals2; 23 | if (vals.length == 0) 24 | return; 25 | //write first array 26 | Object[] prevKey = (Object[]) vals[0]; 27 | out.packInt(prevKey.length); 28 | for (Object key : prevKey) { 29 | serializer.serialize(out, (T) key); 30 | } 31 | 32 | //write remaining arrays 33 | for (int i = 1; i < vals.length; i++) { 34 | Object[] key = (Object[]) vals[i]; 35 | //calculate number of entries equal with prevKey 36 | int len = Math.min(key.length, prevKey.length); 37 | int pos = 0; 38 | while (pos < len && (key[pos] == prevKey[pos] || serializer.equals((T) key[pos], (T) prevKey[pos]))) { 39 | pos++; 40 | } 41 | out.packInt(pos); 42 | //write remaining bytes 43 | out.packInt(key.length - pos); 44 | for (; pos < key.length; pos++) { 45 | serializer.serialize(out, (T) key[pos]); 46 | } 47 | prevKey = key; 48 | } 49 | 50 | } 51 | 52 | @Override 53 | public Object[] valueArrayDeserialize(DataInput2 in, final int size) { 54 | Object[] ret = new Object[size]; 55 | if (size == 0) 56 | return ret; 57 | int ss = in.unpackInt(); 58 | Object[] prevKey = new Object[ss]; 59 | for (int i = 0; i < ss; i++) { 60 | prevKey[i] = serializer.deserialize(in, -1); 61 | } 62 | ret[0] = prevKey; 63 | for (int i = 1; i < size; i++) { 64 | //number of items shared with prev 65 | int shared = in.unpackInt(); 66 | //number of items unique to this array 67 | int unq = in.unpackInt(); 68 | Object[] key = new Object[shared + unq]; 69 | //copy items from prev array 70 | System.arraycopy(prevKey, 0, key, 0, shared); 71 | //and read rest 72 | for (; shared < key.length; shared++) { 73 | key[shared] = serializer.deserialize(in, -1); 74 | } 75 | ret[i] = key; 76 | prevKey = key; 77 | } 78 | return ret; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/ArrayListSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | import org.mapdb.io.DataInput2; 6 | import org.mapdb.io.DataOutput2; 7 | 8 | import java.util.ArrayList; 9 | 10 | public class ArrayListSerializer implements Serializer> { 11 | 12 | protected final Serializer ser; 13 | 14 | public ArrayListSerializer(Serializer ser) { 15 | this.ser = ser; 16 | } 17 | 18 | @Override 19 | public void serialize(@NotNull DataOutput2 out, @NotNull ArrayList list) { 20 | out.writePackedInt(list.size()); 21 | for(E e:list){ 22 | ser.serialize(out,e); 23 | } 24 | } 25 | 26 | @Override 27 | public ArrayList deserialize(@NotNull DataInput2 input) { 28 | final int size = input.readPackedInt(); 29 | ArrayList list = new ArrayList<>(size); 30 | for(int i=0;i extends DefaultGroupSerializer { 22 | 23 | private static final long serialVersionUID = -982394293898234253L; 24 | protected final Serializer serializer; 25 | protected final Class componentType; 26 | 27 | 28 | /** 29 | * Wraps given serializer and produces Object[] serializer. 30 | * To produce array with different component type, specify extra class. 31 | */ 32 | public ArraySerializer(Serializer serializer) { 33 | this(serializer, null); 34 | } 35 | 36 | 37 | /** 38 | * Wraps given serializer and produces array serializer. 39 | * 40 | * @param serializer 41 | * @param componentType type of array which will be created on deserialization 42 | */ 43 | public ArraySerializer(Serializer serializer, Class componentType) { 44 | if (serializer == null) 45 | throw new NullPointerException("null serializer"); 46 | this.serializer = serializer; 47 | this.componentType = componentType!=null 48 | ? componentType 49 | : (Class)Object.class; 50 | } 51 | 52 | // /** used for deserialization */ 53 | // @SuppressWarnings("unchecked") 54 | // protected Array(SerializerBase serializerBase, DataInput2 is, SerializerBase.FastArrayList objectStack) { 55 | // objectStack.add(this); 56 | // this.serializer = (Serializer) serializerBase.deserialize(is,objectStack); 57 | // } 58 | 59 | 60 | @Override 61 | public void serialize(DataOutput2 out, T[] value) { 62 | out.packInt(value.length); 63 | for (T a : value) { 64 | serializer.serialize(out, a); 65 | } 66 | } 67 | 68 | @Override 69 | public T[] deserialize(DataInput2 in) { 70 | int size = in.unpackInt(); 71 | T[] ret = (T[]) Array.newInstance(componentType, size); 72 | for (int i = 0; i < ret.length; i++) { 73 | ret[i] = serializer.deserialize(in, -1); 74 | } 75 | return ret; 76 | 77 | } 78 | 79 | @Nullable 80 | @Override 81 | public Class serializedType() { 82 | return Object[].class; 83 | } 84 | 85 | @Override 86 | public boolean isTrusted() { 87 | return serializer.isTrusted(); 88 | } 89 | 90 | @Override 91 | public boolean equals(T[] a1, T[] a2) { 92 | if (a1 == a2) 93 | return true; 94 | if (a1 == null || a1.length != a2.length) 95 | return false; 96 | 97 | for (int i = 0; i < a1.length; i++) { 98 | if (!serializer.equals(a1[i], a2[i])) 99 | return false; 100 | } 101 | return true; 102 | } 103 | 104 | @Override 105 | public int hashCode(T[] objects, int seed) { 106 | seed += objects.length; 107 | for (T a : objects) { 108 | seed = (-1640531527) * seed + serializer.hashCode(a, seed); 109 | } 110 | return seed; 111 | } 112 | 113 | @Override 114 | public boolean equals(Object o) { 115 | if (this == o) return true; 116 | if (o == null || getClass() != o.getClass()) return false; 117 | return serializer.equals(((ArraySerializer) o).serializer); 118 | } 119 | 120 | @Override 121 | public int hashCode() { 122 | return serializer.hashCode(); 123 | } 124 | 125 | 126 | @Override 127 | public int compare(Object[] o1, Object[] o2) { 128 | int len = Math.min(o1.length, o2.length); 129 | int r; 130 | for (int i = 0; i < len; i++) { 131 | Object a1 = o1[i]; 132 | Object a2 = o2[i]; 133 | 134 | if (a1 == a2) { //this case handles both nulls 135 | r = 0; 136 | } else if (a1 == null) { 137 | r = 1; //null is positive infinity, always greater than anything else 138 | } else if (a2 == null) { 139 | r = -1; 140 | } else { 141 | r = serializer.compare((T) a1, (T) a2); 142 | ; 143 | } 144 | if (r != 0) 145 | return r; 146 | } 147 | return SerializerUtils.compareInt(o1.length, o2.length); 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/BigDecimalSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.math.BigDecimal; 9 | import java.math.BigInteger; 10 | 11 | /** 12 | * Created by jan on 2/28/16. 13 | */ 14 | public class BigDecimalSerializer extends DefaultGroupSerializer { 15 | @Override 16 | public void serialize(DataOutput2 out, BigDecimal value) { 17 | Serializers.BYTE_ARRAY.serialize(out, value.unscaledValue().toByteArray()); 18 | out.packInt(value.scale()); 19 | } 20 | 21 | @Override 22 | public BigDecimal deserialize(DataInput2 in) { 23 | return new BigDecimal(new BigInteger( 24 | Serializers.BYTE_ARRAY.deserialize(in, -1)), 25 | in.unpackInt()); 26 | } 27 | 28 | @Nullable 29 | @Override 30 | public Class serializedType() { 31 | return BigDecimal.class; 32 | } 33 | 34 | @Override 35 | public boolean isTrusted() { 36 | return true; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/BigIntegerSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.math.BigInteger; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class BigIntegerSerializer extends DefaultGroupSerializer { 14 | @Override 15 | public void serialize(DataOutput2 out, BigInteger value) { 16 | Serializers.BYTE_ARRAY.serialize(out, value.toByteArray()); 17 | } 18 | 19 | @Override 20 | public BigInteger deserialize(DataInput2 in) { 21 | return new BigInteger(Serializers.BYTE_ARRAY.deserialize(in)); 22 | } 23 | 24 | @Nullable 25 | @Override 26 | public Class serializedType() { 27 | return BigInteger.class; 28 | } 29 | 30 | @Override 31 | public boolean isTrusted() { 32 | return true; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/BooleanSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | import java.util.Comparator; 10 | 11 | /** 12 | * Created by jan on 2/28/16. 13 | */ 14 | public class BooleanSerializer implements GroupSerializer { 15 | 16 | @Override 17 | public void serialize(DataOutput2 out, Boolean value) { 18 | out.writeBoolean(value); 19 | } 20 | 21 | @Override 22 | public Boolean deserialize(DataInput2 in) { 23 | return in.readBoolean(); 24 | } 25 | 26 | @Nullable 27 | @Override 28 | public Class serializedType() { 29 | return Boolean.class; 30 | } 31 | 32 | @Override 33 | public int fixedSize() { 34 | return 1; 35 | } 36 | 37 | @Override 38 | public boolean isTrusted() { 39 | return true; 40 | } 41 | 42 | 43 | @Override 44 | public int valueArraySearch(boolean[] keys, Boolean key) { 45 | return Arrays.binarySearch(valueArrayToArray(keys), key); 46 | } 47 | 48 | @Override 49 | public int valueArraySearch(boolean[] keys, Boolean key, Comparator comparator) { 50 | return Arrays.binarySearch(valueArrayToArray(keys), key, comparator); 51 | } 52 | 53 | @Override 54 | public void valueArraySerialize(DataOutput2 out, boolean[] vals) { 55 | for (boolean b : ((boolean[]) vals)) { 56 | out.writeBoolean(b); 57 | } 58 | } 59 | 60 | @Override 61 | public boolean[] valueArrayDeserialize(DataInput2 in, int size) { 62 | boolean[] ret = new boolean[size]; 63 | for (int i = 0; i < size; i++) { 64 | ret[i] = in.readBoolean(); 65 | } 66 | return ret; 67 | } 68 | 69 | @Override 70 | public Boolean valueArrayGet(boolean[] vals, int pos) { 71 | return ((boolean[]) vals)[pos]; 72 | } 73 | 74 | @Override 75 | public int valueArraySize(boolean[] vals) { 76 | return ((boolean[]) vals).length; 77 | } 78 | 79 | @Override 80 | public boolean[] valueArrayEmpty() { 81 | return new boolean[0]; 82 | } 83 | 84 | @Override 85 | public boolean[] valueArrayPut(boolean[] vals, int pos, Boolean newValue) { 86 | boolean[] array = (boolean[]) vals; 87 | final boolean[] ret = Arrays.copyOf(array, array.length + 1); 88 | if (pos < array.length) { 89 | System.arraycopy(array, pos, ret, pos + 1, array.length - pos); 90 | } 91 | ret[pos] = newValue; 92 | return ret; 93 | 94 | } 95 | 96 | @Override 97 | public boolean[] valueArrayUpdateVal(boolean[] vals, int pos, Boolean newValue) { 98 | boolean[] vals2 = ((boolean[]) vals).clone(); 99 | vals2[pos] = newValue; 100 | return vals2; 101 | 102 | } 103 | 104 | @Override 105 | public boolean[] valueArrayFromArray(Object[] objects) { 106 | boolean[] ret = new boolean[objects.length]; 107 | for (int i = 0; i < ret.length; i++) { 108 | ret[i] = (Boolean) objects[i]; 109 | } 110 | return ret; 111 | } 112 | 113 | @Override 114 | public boolean[] valueArrayCopyOfRange(boolean[] vals, int from, int to) { 115 | return Arrays.copyOfRange((boolean[]) vals, from, to); 116 | } 117 | 118 | @Override 119 | public boolean[] valueArrayDeleteValue(boolean[] vals, int pos) { 120 | boolean[] valsOrig = (boolean[]) vals; 121 | boolean[] vals2 = new boolean[valsOrig.length - 1]; 122 | System.arraycopy(vals, 0, vals2, 0, pos - 1); 123 | System.arraycopy(vals, pos, vals2, pos - 1, vals2.length - (pos - 1)); 124 | return vals2; 125 | 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/ByteArrayDeltaSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.io.DataInput2; 4 | import org.mapdb.io.DataOutput2; 5 | 6 | import java.io.IOException; 7 | 8 | /** 9 | * Created by jan on 2/29/16. 10 | */ 11 | public class ByteArrayDeltaSerializer extends ByteArraySerializer { 12 | 13 | //TODO PERF char[][] versus Object[] 14 | 15 | @Override 16 | public void valueArraySerialize(DataOutput2 out, byte[][] vals) { 17 | byte[][] chars = (byte[][]) vals; 18 | //write lengths 19 | for(byte[] b:chars){ 20 | out.packInt(b.length); 21 | } 22 | //$DELAY$ 23 | //find common prefix 24 | int prefixLen = commonPrefixLen(chars); 25 | out.packInt(prefixLen); 26 | out.write(chars[0], 0, prefixLen); 27 | //$DELAY$ 28 | for(byte[] b:chars){ 29 | out.write(b,prefixLen,b.length-prefixLen); 30 | } 31 | 32 | 33 | } 34 | 35 | @Override 36 | public byte[][] valueArrayDeserialize(DataInput2 in, int size) { 37 | byte[][] ret = new byte[size][]; 38 | 39 | //read lengths and init arrays 40 | for(int i=0;i { 19 | 20 | @Override 21 | public void serialize(DataOutput2 out, byte[] value) { 22 | out.write(value); 23 | } 24 | 25 | @Override 26 | public byte[] deserialize(@NotNull DataInput2 input) { 27 | int avail = input.available(); 28 | byte[] ret = new byte[avail]; 29 | input.readFully(ret, 0, avail); 30 | return ret; 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public Class serializedType() { 36 | return null; 37 | } 38 | 39 | @Override 40 | public byte[] deserialize(DataInput2 in, int available) { 41 | byte[] ret = new byte[available]; 42 | in.readFully(ret); 43 | return ret; 44 | } 45 | 46 | @Override 47 | public boolean isTrusted() { 48 | return true; 49 | } 50 | 51 | @Override 52 | public boolean equals(byte[] a1, byte[] a2) { 53 | return Arrays.equals(a1, a2); 54 | } 55 | 56 | @Override 57 | public int hashCode(byte[] bytes, int seed) { 58 | return Serializers.BYTE_ARRAY.hashCode(bytes, seed); 59 | } 60 | 61 | @Override 62 | public int compare(byte[] o1, byte[] o2) { 63 | if (o1 == o2) return 0; 64 | final int len = Math.min(o1.length, o2.length); 65 | for (int i = 0; i < len; i++) { 66 | int b1 = o1[i] & 0xFF; 67 | int b2 = o2[i] & 0xFF; 68 | if (b1 != b2) 69 | return b1 - b2; 70 | } 71 | return o1.length - o2.length; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/ByteArraySerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import net.jpountz.xxhash.XXHash32; 4 | import net.jpountz.xxhash.XXHashFactory; 5 | import org.jetbrains.annotations.Nullable; 6 | import org.mapdb.io.DataInput2; 7 | import org.mapdb.io.DataOutput2; 8 | 9 | import java.io.IOException; 10 | import java.util.Arrays; 11 | import java.util.Comparator; 12 | 13 | /** 14 | * Created by jan on 2/28/16. 15 | */ 16 | public class ByteArraySerializer implements GroupSerializer { 17 | 18 | //TODO thread safe? 19 | private static final XXHash32 HASHER = XXHashFactory.fastestInstance().hash32(); 20 | 21 | @Override 22 | public void serialize(DataOutput2 out, byte[] value) { 23 | out.packInt(value.length); 24 | out.write(value); 25 | } 26 | 27 | @Override 28 | public byte[] deserialize(DataInput2 in) { 29 | int size = in.unpackInt(); 30 | byte[] ret = new byte[size]; 31 | in.readFully(ret); 32 | return ret; 33 | } 34 | 35 | @Nullable 36 | @Override 37 | public Class serializedType() { 38 | return byte[].class; 39 | } 40 | 41 | 42 | @Override 43 | public boolean isTrusted() { 44 | return true; 45 | } 46 | 47 | @Override 48 | public boolean equals(byte[] a1, byte[] a2) { 49 | return Arrays.equals(a1, a2); 50 | } 51 | 52 | public int hashCode(byte[] bytes, int seed) { 53 | return HASHER.hash(bytes, 0, bytes.length, seed); 54 | } 55 | 56 | @Override 57 | public int compare(byte[] o1, byte[] o2) { 58 | if (o1 == o2) return 0; 59 | final int len = Math.min(o1.length, o2.length); 60 | for (int i = 0; i < len; i++) { 61 | int b1 = o1[i] & 0xFF; 62 | int b2 = o2[i] & 0xFF; 63 | if (b1 != b2) 64 | return b1 - b2; 65 | } 66 | return o1.length - o2.length; 67 | } 68 | 69 | @Override 70 | public int valueArraySearch(byte[][] keys, byte[] key) { 71 | return Arrays.binarySearch((byte[][])keys, key, Serializers.BYTE_ARRAY); 72 | } 73 | 74 | @Override 75 | public int valueArraySearch(byte[][] keys, byte[] key, Comparator comparator) { 76 | //TODO PERF optimize search 77 | Object[] v = valueArrayToArray(keys); 78 | return Arrays.binarySearch(v, key, comparator); 79 | } 80 | 81 | @Override 82 | public void valueArraySerialize(DataOutput2 out, byte[][] vals) { 83 | byte[][] vals2 = (byte[][]) vals; 84 | out.packInt(vals2.length); 85 | for(byte[]b:vals2){ 86 | Serializers.BYTE_ARRAY.serialize(out, b); 87 | } 88 | } 89 | 90 | @Override 91 | public byte[][] valueArrayDeserialize(DataInput2 in, int size) { 92 | int s = in.unpackInt(); 93 | byte[][] ret = new byte[s][]; 94 | for(int i=0;i { 13 | 14 | //TODO use byte[] group serializer 15 | 16 | @Override 17 | public void serialize(DataOutput2 out, Byte value) { 18 | out.writeByte(value); 19 | } 20 | 21 | @Override 22 | public Byte deserialize(DataInput2 in) { 23 | return in.readByte(); 24 | } 25 | 26 | @Nullable 27 | @Override 28 | public Class serializedType() { 29 | return Byte.class; 30 | } 31 | 32 | //TODO value array operations 33 | 34 | @Override 35 | public int fixedSize() { 36 | return 1; 37 | } 38 | 39 | @Override 40 | public boolean isTrusted() { 41 | return true; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/CharArraySerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class CharArraySerializer extends DefaultGroupSerializer { 14 | 15 | @Override 16 | public void serialize(DataOutput2 out, char[] value) { 17 | out.packInt(value.length); 18 | for (char c : value) { 19 | out.writeChar(c); 20 | } 21 | } 22 | 23 | @Override 24 | public char[] deserialize(DataInput2 in) { 25 | final int size = in.unpackInt(); 26 | char[] ret = new char[size]; 27 | for (int i = 0; i < size; i++) { 28 | ret[i] = in.readChar(); 29 | } 30 | return ret; 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public Class serializedType() { 36 | return char[].class; 37 | } 38 | 39 | @Override 40 | public boolean isTrusted() { 41 | return true; 42 | } 43 | 44 | @Override 45 | public boolean equals(char[] a1, char[] a2) { 46 | return Arrays.equals(a1, a2); 47 | } 48 | 49 | @Override 50 | public int hashCode(char[] chars, int seed) { 51 | int res = 0; 52 | for (char c : chars) { 53 | res = (res + c) * -1640531527 ; 54 | } 55 | return res; 56 | } 57 | 58 | @Override 59 | public int compare(char[] o1, char[] o2) { 60 | final int len = Math.min(o1.length, o2.length); 61 | for (int i = 0; i < len; i++) { 62 | int b1 = o1[i]; 63 | int b2 = o2[i]; 64 | if (b1 != b2) 65 | return b1 - b2; 66 | } 67 | return SerializerUtils.compareInt(o1.length, o2.length); 68 | } 69 | 70 | @Override 71 | public char[] nextValue(char[] value) { 72 | value = value.clone(); 73 | 74 | for (int i = value.length-1; ;i--) { 75 | char b1 = value[i]; 76 | if(b1==Character.MAX_VALUE){ 77 | if(i==0) 78 | return null; 79 | value[i]=Character.MIN_VALUE; 80 | continue; 81 | } 82 | value[i] = (char) (b1+1); 83 | return value; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/CharSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * Created by jan on 2/28/16. 11 | */ 12 | public class CharSerializer extends DefaultGroupSerializer { 13 | @Override 14 | public void serialize(DataOutput2 out, Character value) { 15 | out.writeChar(value.charValue()); 16 | } 17 | 18 | @Override 19 | public Character deserialize(DataInput2 in) { 20 | return in.readChar(); 21 | } 22 | 23 | @Nullable 24 | @Override 25 | public Class serializedType() { 26 | return Character.class; 27 | } 28 | 29 | @Override 30 | public int fixedSize() { 31 | return 2; 32 | } 33 | 34 | @Override 35 | public boolean isTrusted() { 36 | return true; 37 | } 38 | 39 | //TODO value array 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/ClassSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.DBException; 5 | import org.mapdb.io.DataInput2; 6 | import org.mapdb.io.DataOutput2; 7 | 8 | import java.io.IOException; 9 | 10 | /** 11 | * Serialier for class. It takes a class loader as constructor param, by default it uses 12 | * {@code Thread.currentThread().getContextClassLoader()} 13 | */ 14 | public class ClassSerializer extends DefaultGroupSerializer { 15 | 16 | protected final ClassLoader classLoader; 17 | 18 | public ClassSerializer(ClassLoader classLoader) { 19 | this.classLoader = classLoader; 20 | } 21 | 22 | public ClassSerializer(){ 23 | this(Thread.currentThread().getContextClassLoader()); 24 | } 25 | 26 | @Override 27 | public void serialize(DataOutput2 out, Class value) { 28 | out.writeUTF(value.getName()); 29 | } 30 | 31 | @Override 32 | public Class deserialize(DataInput2 in) { 33 | try { 34 | return classLoader.loadClass(in.readUTF()); 35 | } catch (ClassNotFoundException e) { 36 | throw new DBException.SerializationError(e); 37 | } 38 | } 39 | 40 | @Nullable 41 | @Override 42 | public Class serializedType() { 43 | return Class.class; 44 | } 45 | 46 | @Override 47 | public boolean isTrusted() { 48 | return true; 49 | } 50 | 51 | @Override 52 | public boolean equals(Class a1, Class a2) { 53 | return a1 == a2 || (a1.toString().equals(a2.toString())); 54 | } 55 | 56 | @Override 57 | public int hashCode(Class aClass, int seed) { 58 | //class does not override identity hash code 59 | return aClass.toString().hashCode(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/DateSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | import java.util.Date; 10 | 11 | /** 12 | * Created by jan on 2/28/16. 13 | */ 14 | public class DateSerializer extends EightByteSerializer { 15 | 16 | @Override 17 | public void serialize(DataOutput2 out, Date value) { 18 | out.writeLong(value.getTime()); 19 | } 20 | 21 | @Override 22 | public Date deserialize(DataInput2 in) { 23 | return new Date(in.readLong()); 24 | } 25 | 26 | @Nullable 27 | @Override 28 | public Class serializedType() { 29 | return Date.class; 30 | } 31 | 32 | @Override 33 | protected Date unpack(long l) { 34 | return new Date(l); 35 | } 36 | 37 | @Override 38 | protected long pack(Date l) { 39 | return l.getTime(); 40 | } 41 | 42 | @Override 43 | final public int valueArraySearch(long[] keys, Date key) { 44 | //TODO valueArraySearch versus comparator test 45 | long time = key.getTime(); 46 | return Arrays.binarySearch((long[])keys, time); 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/DefaultGroupSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.io.DataIO; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | import java.util.Comparator; 10 | 11 | /** 12 | * Created by jan on 2/29/16. 13 | */ 14 | public abstract class DefaultGroupSerializer implements GroupSerializer { 15 | 16 | 17 | @Override public void valueArraySerialize(DataOutput2 out, Object[] vals) { 18 | for(Object o:vals){ 19 | serialize(out, (A)o); 20 | } 21 | } 22 | 23 | @Override public Object[] valueArrayDeserialize(DataInput2 in, int size) { 24 | Object[] ret = new Object[size]; 25 | for(int i=0;i)this); 68 | } 69 | 70 | @Override public Object[] valueArrayToArray(Object[] vals){ 71 | return (Object[]) vals; 72 | } 73 | @Override public int valueArraySearch(Object[] keys, A key, Comparator comparator){ 74 | if(comparator==this) 75 | return valueArraySearch(keys, key); 76 | return Arrays.binarySearch(keys, key, comparator); 77 | } 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/DoubleArraySerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class DoubleArraySerializer extends DefaultGroupSerializer { 14 | 15 | @Override 16 | public void serialize(DataOutput2 out, double[] value) { 17 | out.packInt(value.length); 18 | for (double c : value) { 19 | out.writeDouble(c); 20 | } 21 | } 22 | 23 | @Override 24 | public double[] deserialize(DataInput2 in) { 25 | final int size = in.unpackInt(); 26 | double[] ret = new double[size]; 27 | for (int i = 0; i < size; i++) { 28 | ret[i] = in.readDouble(); 29 | } 30 | return ret; 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public Class serializedType() { 36 | return double[].class; 37 | } 38 | 39 | 40 | @Override 41 | public boolean isTrusted() { 42 | return true; 43 | } 44 | 45 | @Override 46 | public boolean equals(double[] a1, double[] a2) { 47 | return Arrays.equals(a1, a2); 48 | } 49 | 50 | @Override 51 | public int hashCode(double[] bytes, int seed) { 52 | for (double element : bytes) { 53 | long bits = Double.doubleToLongBits(element); 54 | seed = (-1640531527) * seed + (int) (bits ^ (bits >>> 32)); 55 | } 56 | return seed; 57 | } 58 | 59 | @Override 60 | public int compare(double[] o1, double[] o2) { 61 | if (o1 == o2) return 0; 62 | final int len = Math.min(o1.length, o2.length); 63 | for (int i = 0; i < len; i++) { 64 | if (o1[i] == o2[i]) 65 | continue; 66 | if (o1[i] > o2[i]) 67 | return 1; 68 | return -1; 69 | } 70 | return SerializerUtils.compareInt(o1.length, o2.length); 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/DoubleSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class DoubleSerializer extends EightByteSerializer { 14 | @Override 15 | protected Double unpack(long l) { 16 | return new Double(Double.longBitsToDouble(l)); 17 | } 18 | 19 | @Override 20 | protected long pack(Double l) { 21 | return Double.doubleToLongBits(l); 22 | } 23 | 24 | @Override 25 | public int valueArraySearch(long[] keys, Double key) { 26 | //TODO PERF this can be optimized, but must take care of NaN 27 | return Arrays.binarySearch(valueArrayToArray(keys), key); 28 | } 29 | 30 | @Override 31 | public void serialize(DataOutput2 out, Double value) { 32 | out.writeDouble(value); 33 | } 34 | 35 | @Override 36 | public Double deserialize(DataInput2 in) { 37 | return new Double(in.readDouble()); 38 | } 39 | 40 | @Nullable 41 | @Override 42 | public Class serializedType() { 43 | return Double.class; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/EightByteSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.io.DataInput2; 4 | import org.mapdb.io.DataOutput2; 5 | 6 | import java.io.IOException; 7 | import java.util.Arrays; 8 | import java.util.Comparator; 9 | 10 | public abstract class EightByteSerializer implements GroupSerializer { 11 | 12 | protected abstract E unpack(long l); 13 | protected abstract long pack(E l); 14 | 15 | @Override 16 | public E valueArrayGet(long[] vals, int pos){ 17 | return unpack(((long[]) vals)[pos]); 18 | } 19 | 20 | 21 | @Override 22 | public int valueArraySize(long[] vals){ 23 | return ((long[])vals).length; 24 | } 25 | 26 | @Override 27 | public long[] valueArrayEmpty(){ 28 | return new long[0]; 29 | } 30 | 31 | @Override 32 | public long[] valueArrayPut(long[] vals, int pos, E newValue) { 33 | 34 | long[] array = (long[]) vals; 35 | final long[] ret = Arrays.copyOf(array, array.length+1); 36 | if(pos>> 1; 122 | int compare = comparator.compare(key, unpack(array[mid])); 123 | 124 | if (compare == 0) 125 | return mid; 126 | else if (compare < 0) 127 | hi = mid - 1; 128 | else 129 | lo = mid + 1; 130 | } 131 | return -(lo + 1); 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/FloatArraySerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class FloatArraySerializer extends DefaultGroupSerializer { 14 | @Override 15 | public void serialize(DataOutput2 out, float[] value) { 16 | out.packInt(value.length); 17 | for (float v : value) { 18 | out.writeFloat(v); 19 | } 20 | } 21 | 22 | @Override 23 | public float[] deserialize(DataInput2 in) { 24 | float[] ret = new float[in.unpackInt()]; 25 | for (int i = 0; i < ret.length; i++) { 26 | ret[i] = in.readFloat(); 27 | } 28 | return ret; 29 | } 30 | 31 | @Nullable 32 | @Override 33 | public Class serializedType() { 34 | return float[].class; 35 | } 36 | 37 | @Override 38 | public boolean isTrusted() { 39 | return true; 40 | } 41 | 42 | @Override 43 | public boolean equals(float[] a1, float[] a2) { 44 | return Arrays.equals(a1, a2); 45 | } 46 | 47 | @Override 48 | public int hashCode(float[] floats, int seed) { 49 | for (float element : floats) 50 | seed = (-1640531527) * seed + Float.floatToIntBits(element); 51 | return seed; 52 | } 53 | 54 | @Override 55 | public int compare(float[] o1, float[] o2) { 56 | if (o1 == o2) return 0; 57 | final int len = Math.min(o1.length, o2.length); 58 | for (int i = 0; i < len; i++) { 59 | if (o1[i] == o2[i]) 60 | continue; 61 | if (o1[i] > o2[i]) 62 | return 1; 63 | return -1; 64 | } 65 | return SerializerUtils.compareInt(o1.length, o2.length); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/FloatSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class FloatSerializer extends FourByteSerializer { 14 | 15 | @Override 16 | protected Float unpack(int l) { 17 | return new Float(Float.intBitsToFloat(l)); 18 | } 19 | 20 | @Override 21 | protected int pack(Float l) { 22 | return Float.floatToIntBits(l); 23 | } 24 | 25 | 26 | @Override 27 | public void serialize(DataOutput2 out, Float value) { 28 | out.writeFloat(value); 29 | } 30 | 31 | @Override 32 | public Float deserialize(DataInput2 in) { 33 | return new Float(in.readFloat()); 34 | } 35 | 36 | @Nullable 37 | @Override 38 | public Class serializedType() { 39 | return Float.class; 40 | } 41 | 42 | 43 | @Override 44 | public int valueArraySearch(int[] keys, Float key) { 45 | //TODO PERF this can be optimized, but must take care of NaN 46 | return Arrays.binarySearch(valueArrayToArray(keys), key); 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/FourByteSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.io.DataInput2; 4 | import org.mapdb.io.DataOutput2; 5 | 6 | import java.io.IOException; 7 | import java.util.Arrays; 8 | import java.util.Comparator; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public abstract class FourByteSerializer implements GroupSerializer { 14 | 15 | protected abstract E unpack(int l); 16 | 17 | protected abstract int pack(E l); 18 | 19 | @Override 20 | public boolean isTrusted() { 21 | return true; 22 | } 23 | 24 | @Override 25 | public int fixedSize() { 26 | return 4; 27 | } 28 | 29 | @Override 30 | public E valueArrayGet(int[] vals, int pos) { 31 | return unpack(((int[]) vals)[pos]); 32 | } 33 | 34 | @Override 35 | public int valueArraySize(int[] vals) { 36 | return ((int[]) vals).length; 37 | } 38 | 39 | @Override 40 | public int[] valueArrayEmpty() { 41 | return new int[0]; 42 | } 43 | 44 | @Override 45 | public int[] valueArrayPut(int[] vals, int pos, E newValue) { 46 | 47 | final int[] ret = Arrays.copyOf(vals, vals.length + 1); 48 | if (pos < vals.length) { 49 | System.arraycopy(vals, pos, ret, pos + 1, vals.length - pos); 50 | } 51 | ret[pos] = pack(newValue); 52 | return ret; 53 | } 54 | 55 | @Override 56 | public int[] valueArrayUpdateVal(int[] vals, int pos, E newValue) { 57 | int[] vals2 = ((int[]) vals).clone(); 58 | vals2[pos] = pack(newValue); 59 | return vals2; 60 | } 61 | 62 | @Override 63 | public int[] valueArrayFromArray(Object[] objects) { 64 | int[] ret = new int[objects.length]; 65 | int pos = 0; 66 | 67 | for (Object o : objects) { 68 | ret[pos++] = pack((E) o); 69 | } 70 | 71 | return ret; 72 | } 73 | 74 | @Override 75 | public int[] valueArrayCopyOfRange(int[] vals, int from, int to) { 76 | return Arrays.copyOfRange((int[]) vals, from, to); 77 | } 78 | 79 | @Override 80 | public int[] valueArrayDeleteValue(int[] vals, int pos) { 81 | int[] valsOrig = (int[]) vals; 82 | int[] vals2 = new int[valsOrig.length - 1]; 83 | System.arraycopy(vals, 0, vals2, 0, pos - 1); 84 | System.arraycopy(vals, pos, vals2, pos - 1, vals2.length - (pos - 1)); 85 | return vals2; 86 | } 87 | 88 | 89 | @Override 90 | public void valueArraySerialize(DataOutput2 out, int[] vals) { 91 | for (int o : (int[]) vals) { 92 | out.writeInt(o); 93 | } 94 | } 95 | 96 | @Override 97 | public int[] valueArrayDeserialize(DataInput2 in, int size) { 98 | int[] ret = new int[size]; 99 | for (int i = 0; i < size; i++) { 100 | ret[i] = in.readInt(); 101 | } 102 | return ret; 103 | } 104 | 105 | @Override 106 | final public int valueArraySearch(int[] keys, E key, Comparator comparator) { 107 | if (comparator == this) 108 | return valueArraySearch(keys, key); 109 | 110 | int lo = 0; 111 | int hi = keys.length - 1; 112 | 113 | while (lo <= hi) { 114 | int mid = (lo + hi) >>> 1; 115 | int compare = comparator.compare(key, unpack(keys[mid])); 116 | 117 | if (compare == 0) 118 | return mid; 119 | else if (compare < 0) 120 | hi = mid - 1; 121 | else 122 | lo = mid + 1; 123 | } 124 | return -(lo + 1); 125 | } 126 | 127 | @Override 128 | public E valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { 129 | input.skipBytes(pos*4); 130 | return unpack(input.readInt()); 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/GroupSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.io.DataInput2; 4 | import org.mapdb.io.DataOutput2; 5 | 6 | import java.io.IOException; 7 | import java.util.Comparator; 8 | 9 | /** 10 | * Created by jan on 2/29/16. 11 | */ 12 | public interface GroupSerializer extends Serializer { 13 | 14 | default A valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { 15 | G keys = valueArrayDeserialize(input, keysLen); 16 | return valueArrayGet(keys, pos); 17 | // A a=null; 18 | // while(pos-- >= 0){ 19 | // a = deserialize(input, -1); 20 | // } 21 | // return a; 22 | } 23 | 24 | 25 | 26 | default int valueArrayBinarySearch(A key, DataInput2 input, int keysLen, Comparator comparator) { 27 | G keys = valueArrayDeserialize(input, keysLen); 28 | return valueArraySearch(keys, key, comparator); 29 | // for(int pos=0; pos { 14 | 15 | @Override 16 | public void serialize(DataOutput2 out, int[] value) { 17 | out.packInt(value.length); 18 | for (int c : value) { 19 | out.writeInt(c); 20 | } 21 | } 22 | 23 | @Override 24 | public int[] deserialize(DataInput2 in) { 25 | final int size = in.unpackInt(); 26 | int[] ret = new int[size]; 27 | for (int i = 0; i < size; i++) { 28 | ret[i] = in.readInt(); 29 | } 30 | return ret; 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public Class serializedType() { 36 | return int[].class; 37 | } 38 | 39 | @Override 40 | public boolean isTrusted() { 41 | return true; 42 | } 43 | 44 | @Override 45 | public boolean equals(int[] a1, int[] a2) { 46 | return Arrays.equals(a1, a2); 47 | } 48 | 49 | @Override 50 | public int hashCode(int[] bytes, int seed) { 51 | for (int i : bytes) { 52 | seed = (-1640531527) * seed + i; 53 | } 54 | return seed; 55 | } 56 | 57 | @Override 58 | public int compare(int[] o1, int[] o2) { 59 | if (o1 == o2) return 0; 60 | final int len = Math.min(o1.length, o2.length); 61 | for (int i = 0; i < len; i++) { 62 | if (o1[i] == o2[i]) 63 | continue; 64 | if (o1[i] > o2[i]) 65 | return 1; 66 | return -1; 67 | } 68 | return SerializerUtils.compareInt(o1.length, o2.length); 69 | } 70 | 71 | @Override 72 | public int[] nextValue(int[] value) { 73 | value = value.clone(); 74 | 75 | for (int i = value.length-1; ;i--) { 76 | int b1 = value[i]; 77 | if(b1==Integer.MAX_VALUE){ 78 | if(i==0) 79 | return null; 80 | value[i]=Integer.MIN_VALUE; 81 | continue; 82 | } 83 | value[i] = b1+1; 84 | return value; 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/IntegerDeltaSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.CC; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Comparator; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class IntegerDeltaSerializer extends IntegerSerializer { 14 | @Override 15 | public void serialize(DataOutput2 out, Integer value) { 16 | out.packInt(value); 17 | } 18 | 19 | @Override 20 | public Integer deserialize(DataInput2 in, int available) { 21 | return new Integer(in.unpackInt()); 22 | } 23 | 24 | @Override 25 | public void valueArraySerialize(DataOutput2 out, int[] vals) { 26 | int[] keys = (int[]) vals; 27 | int prev = keys[0]; 28 | out.packInt(prev); 29 | for (int i = 1; i < keys.length; i++) { 30 | int curr = keys[i]; 31 | //$DELAY$ 32 | out.packInt(curr - prev); 33 | if (CC.ASSERT && curr < prev) 34 | throw new AssertionError("not sorted"); 35 | prev = curr; 36 | } 37 | } 38 | 39 | @Override 40 | public int[] valueArrayDeserialize(DataInput2 in, int size) { 41 | int[] ret = new int[size]; 42 | int prev = 0; 43 | for (int i = 0; i < size; i++) { 44 | //$DELAY$ 45 | prev += in.unpackInt(); 46 | ret[i] = prev; 47 | } 48 | return ret; 49 | } 50 | 51 | 52 | @Override 53 | public Integer valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { 54 | int a = 0; 55 | while (pos-- >= 0) { 56 | a += input.unpackInt(); 57 | } 58 | return a; 59 | } 60 | 61 | 62 | @Override 63 | public int valueArrayBinarySearch(Integer key, DataInput2 input, int keysLen, Comparator comparator) { 64 | if (comparator != this) 65 | return super.valueArrayBinarySearch(key, input, keysLen, comparator); 66 | int key2 = key; 67 | int from = 0; 68 | for (int pos = 0; pos < keysLen; pos++) { 69 | from += input.unpackInt(); 70 | 71 | if (key2 <= from) { 72 | input.unpackLongSkip(keysLen-pos-1); 73 | return (key2 == from) ? pos : -(pos + 1); 74 | } 75 | } 76 | 77 | //not found 78 | return -(keysLen + 1); 79 | } 80 | 81 | @Override 82 | public int fixedSize() { 83 | return -1; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/IntegerPackedSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.io.DataInput2; 4 | import org.mapdb.io.DataOutput2; 5 | 6 | import java.io.IOException; 7 | import java.util.Comparator; 8 | 9 | /** 10 | * Created by jan on 2/28/16. 11 | */ 12 | public class IntegerPackedSerializer extends IntegerSerializer { 13 | @Override 14 | public void serialize(DataOutput2 out, Integer value) { 15 | out.packInt(value); 16 | } 17 | 18 | @Override 19 | public Integer deserialize(DataInput2 in, int available) { 20 | return new Integer(in.unpackInt()); 21 | } 22 | 23 | @Override 24 | public void valueArraySerialize(DataOutput2 out, int[] vals) { 25 | for (int o : (int[])vals) { 26 | out.packInt(o); //TODO packIntBigger() 27 | } 28 | } 29 | 30 | @Override 31 | public int[] valueArrayDeserialize(DataInput2 in, int size) { 32 | int[] ret = new int[size]; 33 | //TODO int arrays 34 | // in.unpackIntArray(ret, 0, size); 35 | return ret; 36 | } 37 | 38 | @Override 39 | public int fixedSize() { 40 | return -1; 41 | } 42 | 43 | @Override 44 | public int valueArrayBinarySearch(Integer key, DataInput2 input, int keysLen, Comparator comparator) { 45 | if (comparator != this) 46 | return super.valueArrayBinarySearch(key, input, keysLen, comparator); 47 | int key2 = key; 48 | for (int pos = 0; pos < keysLen; pos++) { 49 | int from = input.unpackInt(); 50 | 51 | if (key2 <= from) { 52 | input.unpackLongSkip(keysLen-pos-1); 53 | return (key2 == from) ? pos : -(pos + 1); 54 | } 55 | } 56 | 57 | //not found 58 | return -(keysLen + 1); 59 | } 60 | 61 | @Override 62 | public Integer valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { 63 | input.unpackLongSkip(pos); 64 | return input.unpackInt(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/IntegerSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | import java.util.Comparator; 10 | 11 | public class IntegerSerializer extends FourByteSerializer { 12 | 13 | 14 | @Override 15 | public void serialize(DataOutput2 out, Integer value) { 16 | out.writeInt(value); 17 | } 18 | 19 | @Override 20 | public Integer deserialize(DataInput2 in) { 21 | return new Integer(in.readInt()); 22 | } 23 | 24 | @Nullable 25 | @Override 26 | public Class serializedType() { 27 | return Integer.class; 28 | } 29 | 30 | @Override 31 | protected Integer unpack(int l) { 32 | return new Integer(l); 33 | } 34 | 35 | @Override 36 | protected int pack(Integer l) { 37 | return l; 38 | } 39 | 40 | @Override 41 | public int valueArraySearch(int[] keys, Integer key) { 42 | return Arrays.binarySearch((int[]) keys, key); 43 | } 44 | 45 | 46 | @Override 47 | public int valueArrayBinarySearch(Integer key, DataInput2 input, int keysLen, Comparator comparator) { 48 | if (comparator != this) 49 | return super.valueArrayBinarySearch(key, input, keysLen, comparator); 50 | final int key2 = key; 51 | for (int pos = 0; pos < keysLen; pos++) { 52 | int from = input.readInt(); 53 | 54 | if (key2 <= from) { 55 | input.skipBytes((keysLen-pos-1)*4); 56 | return (key2 == from) ? pos : -(pos + 1); 57 | } 58 | } 59 | 60 | //not found 61 | return -(keysLen + 1); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/JavaSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.CC; 5 | import org.mapdb.DBException; 6 | import org.mapdb.io.DataInput2; 7 | import org.mapdb.io.DataInputToStream; 8 | import org.mapdb.io.DataOutput2; 9 | 10 | import java.io.*; 11 | 12 | /** 13 | * Created by jan on 2/28/16. 14 | */ 15 | public class JavaSerializer extends DefaultGroupSerializer { 16 | @Override 17 | public void serialize(DataOutput2 out, E value) { 18 | ObjectOutputStream out2 = null; 19 | try { 20 | out2 = new ObjectOutputStream((OutputStream) out); 21 | out2.writeObject(value); 22 | out2.flush(); 23 | } catch (IOException e) { 24 | throw new IOError(e); 25 | } 26 | } 27 | 28 | @Override 29 | public E deserialize(DataInput2 in) { 30 | try { 31 | ObjectInputStream in2 = new ObjectInputStream(new DataInputToStream(in)); 32 | return (E) in2.readObject(); 33 | } catch (ClassNotFoundException e) { 34 | throw new DBException.SerializationError(e); 35 | } catch (IOException e) { 36 | throw new IOError(e); 37 | } 38 | } 39 | 40 | @Nullable 41 | @Override 42 | public Class serializedType() { 43 | return Object.class; 44 | } 45 | 46 | @Override 47 | public Object[] valueArrayDeserialize(DataInput2 in, int size) { 48 | try { 49 | ObjectInputStream in2 = new ObjectInputStream(new DataInputToStream(in)); 50 | Object[] ret = (Object[]) in2.readObject(); 51 | if(CC.PARANOID && size!=valueArraySize(ret)) 52 | throw new AssertionError(); 53 | return ret; 54 | } catch (ClassNotFoundException e) { 55 | throw new DBException.SerializationError(e); 56 | } catch (IOException e) { 57 | throw new IOError(e); 58 | } 59 | } 60 | 61 | @Override 62 | public void valueArraySerialize(DataOutput2 out, Object[] vals) { 63 | try{ 64 | ObjectOutputStream out2 = new ObjectOutputStream((OutputStream) out); 65 | out2.writeObject(vals); 66 | out2.flush(); 67 | } catch (IOException e) { 68 | throw new IOError(e); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/LongArraySerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class LongArraySerializer extends DefaultGroupSerializer { 14 | 15 | @Override 16 | public void serialize(DataOutput2 out, long[] value) { 17 | out.packInt(value.length); 18 | for (long c : value) { 19 | out.writeLong(c); 20 | } 21 | } 22 | 23 | @Override 24 | public long[] deserialize(DataInput2 in) { 25 | final int size = in.unpackInt(); 26 | long[] ret = new long[size]; 27 | for (int i = 0; i < size; i++) { 28 | ret[i] = in.readLong(); 29 | } 30 | return ret; 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public Class serializedType() { 36 | return long[].class; 37 | } 38 | 39 | 40 | @Override 41 | public boolean isTrusted() { 42 | return true; 43 | } 44 | 45 | @Override 46 | public boolean equals(long[] a1, long[] a2) { 47 | return Arrays.equals(a1, a2); 48 | } 49 | 50 | @Override 51 | public int hashCode(long[] bytes, int seed) { 52 | for (long element : bytes) { 53 | int elementHash = (int) (element ^ (element >>> 32)); 54 | seed = (-1640531527) * seed + elementHash; 55 | } 56 | return seed; 57 | } 58 | 59 | @Override 60 | public int compare(long[] o1, long[] o2) { 61 | if (o1 == o2) return 0; 62 | final int len = Math.min(o1.length, o2.length); 63 | for (int i = 0; i < len; i++) { 64 | if (o1[i] == o2[i]) 65 | continue; 66 | if (o1[i] > o2[i]) 67 | return 1; 68 | return -1; 69 | } 70 | return SerializerUtils.compareInt(o1.length, o2.length); 71 | } 72 | 73 | @Override 74 | public long[] nextValue(long[] value) { 75 | value = value.clone(); 76 | 77 | for (int i = value.length-1; ;i--) { 78 | long b1 = value[i]; 79 | if(b1==Long.MAX_VALUE){ 80 | if(i==0) 81 | return null; 82 | value[i]=Long.MIN_VALUE; 83 | continue; 84 | } 85 | value[i] = b1+1L; 86 | return value; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/LongDeltaSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.CC; 4 | import org.mapdb.DBException; 5 | import org.mapdb.io.DataInput2; 6 | import org.mapdb.io.DataOutput2; 7 | 8 | import java.io.IOException; 9 | import java.util.Comparator; 10 | 11 | /** 12 | * Created by jan on 2/28/16. 13 | */ 14 | public class LongDeltaSerializer extends LongSerializer { 15 | @Override 16 | public void serialize(DataOutput2 out, Long value) { 17 | out.writePackedLong(value); 18 | } 19 | 20 | @Override 21 | public Long deserialize(DataInput2 in, int available) { 22 | return new Long(in.readPackedLong()); 23 | } 24 | 25 | @Override 26 | public void valueArraySerialize(DataOutput2 out, long[] vals) { 27 | long[] keys = (long[]) vals; 28 | long prev = keys[0]; 29 | out.writePackedLong(prev); 30 | for (int i = 1; i < keys.length; i++) { 31 | long curr = keys[i]; 32 | //$DELAY$ 33 | out.writePackedLong(curr - prev); 34 | if (CC.ASSERT && curr < prev) 35 | throw new AssertionError("not sorted"); 36 | prev = curr; 37 | } 38 | } 39 | 40 | @Override 41 | public long[] valueArrayDeserialize(DataInput2 in, int size) { 42 | throw new DBException.TODO("delta packing"); 43 | // return in.unpackLongArrayDeltaCompression(size); 44 | } 45 | 46 | 47 | @Override 48 | public Long valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { 49 | long a = 0; 50 | while (pos-- >= 0) { 51 | a += input.readPackedLong(); 52 | } 53 | return a; 54 | } 55 | 56 | @Override 57 | public int valueArrayBinarySearch(Long key, DataInput2 input, int keysLen, Comparator comparator) { 58 | if (comparator != this) 59 | return super.valueArrayBinarySearch(key, input, keysLen, comparator); 60 | long key2 = key; 61 | long from = 0; 62 | for (int pos = 0; pos < keysLen; pos++) { 63 | from += input.readPackedLong(); 64 | 65 | if (key2 <= from) { 66 | input.unpackLongSkip(keysLen-pos-1); 67 | return (key2 == from) ? pos : -(pos + 1); 68 | } 69 | } 70 | 71 | //not found 72 | return -(keysLen + 1); 73 | } 74 | 75 | 76 | @Override 77 | public int fixedSize() { 78 | return -1; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/LongPackedSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.DBException; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Comparator; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class LongPackedSerializer extends LongSerializer { 14 | @Override 15 | public void serialize(DataOutput2 out, Long value) { 16 | out.writePackedLong(value); 17 | } 18 | 19 | @Override 20 | public Long deserialize(DataInput2 in, int available) { 21 | return new Long(in.readPackedLong()); 22 | } 23 | 24 | @Override 25 | public void valueArraySerialize(DataOutput2 out, long[] vals) { 26 | for (long o : (long[])vals) { 27 | out.writePackedLong(o); 28 | } 29 | } 30 | 31 | @Override 32 | public long[] valueArrayDeserialize(DataInput2 in, int size) { 33 | long[] ret = new long[size]; 34 | throw new DBException.TODO("packed long"); 35 | // in.unpackLongArray(ret, 0, size); 36 | // return ret; 37 | } 38 | 39 | @Override 40 | public int fixedSize() { 41 | return -1; 42 | } 43 | 44 | @Override 45 | public int valueArrayBinarySearch(Long key, DataInput2 input, int keysLen, Comparator comparator) { 46 | if (comparator != this) 47 | return super.valueArrayBinarySearch(key, input, keysLen, comparator); 48 | long key2 = key; 49 | for (int pos = 0; pos < keysLen; pos++) { 50 | long from = input.readPackedLong(); 51 | 52 | if (key2 <= from) { 53 | input.unpackLongSkip(keysLen - pos - 1); 54 | return (key2 == from) ? pos : -(pos + 1); 55 | } 56 | } 57 | 58 | //not found 59 | return -(keysLen + 1); 60 | } 61 | 62 | @Override 63 | public Long valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { 64 | input.unpackLongSkip(pos); 65 | return input.readPackedLong(); 66 | } 67 | 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/LongSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | import java.util.Comparator; 10 | 11 | /** 12 | * Created by jan on 2/28/16. 13 | */ 14 | public class LongSerializer extends EightByteSerializer { 15 | 16 | @Override 17 | public void serialize(DataOutput2 out, Long value) { 18 | out.writeLong(value); 19 | } 20 | 21 | @Override 22 | public Long deserialize(DataInput2 in) { 23 | return new Long(in.readLong()); 24 | } 25 | 26 | @Nullable 27 | @Override 28 | public Class serializedType() { 29 | return long[].class; 30 | } 31 | 32 | 33 | @Override 34 | protected Long unpack(long l) { 35 | return new Long(l); 36 | } 37 | 38 | @Override 39 | protected long pack(Long l) { 40 | return l.longValue(); 41 | } 42 | 43 | @Override 44 | public int valueArraySearch(long[] keys, Long key) { 45 | return Arrays.binarySearch((long[])keys, key); 46 | } 47 | 48 | 49 | @Override 50 | public int valueArrayBinarySearch(Long key, DataInput2 input, int keysLen, Comparator comparator) { 51 | if (comparator != this) 52 | return super.valueArrayBinarySearch(key, input, keysLen, comparator); 53 | long key2 = key; 54 | for (int pos = 0; pos < keysLen; pos++) { 55 | long from = input.readLong(); 56 | 57 | if (key2 <= from) { 58 | input.skipBytes((keysLen-pos-1)*8); 59 | return (key2 == from) ? pos : -(pos + 1); 60 | } 61 | } 62 | 63 | //not found 64 | return -(keysLen + 1); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/RecidArraySerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.io.DataIO; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * Created by jan on 2/28/16. 11 | */ 12 | public class RecidArraySerializer extends LongArraySerializer{ 13 | 14 | @Override 15 | public void serialize(DataOutput2 out, long[] value) { 16 | out.packInt(value.length); 17 | for (long recid : value) { 18 | DataIO.packRecid(out, recid); 19 | } 20 | } 21 | 22 | @Override 23 | public long[] deserialize(DataInput2 in, int available) { 24 | int size = in.unpackInt(); 25 | long[] ret = new long[size]; 26 | for (int i = 0; i < size; i++) { 27 | ret[i] = DataIO.unpackRecid(in); 28 | } 29 | return ret; 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/RecidSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataIO; 5 | import org.mapdb.io.DataInput2; 6 | import org.mapdb.io.DataOutput2; 7 | 8 | import java.io.IOException; 9 | import java.util.Arrays; 10 | 11 | /** 12 | * Created by jan on 2/28/16. 13 | */ 14 | public class RecidSerializer extends EightByteSerializer { 15 | 16 | @Override 17 | public void serialize(DataOutput2 out, Long value) { 18 | DataIO.packRecid(out, value); 19 | } 20 | 21 | @Override 22 | public Long deserialize(DataInput2 in) { 23 | return new Long(DataIO.unpackRecid(in)); 24 | } 25 | 26 | @Nullable 27 | @Override 28 | public Class serializedType() { 29 | return Long.class; 30 | } 31 | 32 | @Override 33 | public int fixedSize() { 34 | return -1; 35 | } 36 | 37 | @Override 38 | protected Long unpack(long l) { 39 | return new Long(l); 40 | } 41 | 42 | @Override 43 | protected long pack(Long l) { 44 | return l; 45 | } 46 | 47 | @Override 48 | public boolean isTrusted() { 49 | return true; 50 | } 51 | 52 | 53 | @Override 54 | public int valueArraySearch(long[] keys, Long key) { 55 | return Arrays.binarySearch((long[])keys, key); 56 | } 57 | 58 | @Override 59 | public void valueArraySerialize(DataOutput2 out, long[] vals) { 60 | for (long o : (long[]) vals) { 61 | DataIO.packRecid(out, o); 62 | } 63 | } 64 | 65 | @Override 66 | public long[] valueArrayDeserialize(DataInput2 in, int size) { 67 | long[] ret = new long[size]; 68 | for (int i = 0; i < size; i++) { 69 | ret[i] = DataIO.unpackRecid(in); 70 | } 71 | return ret; 72 | } 73 | 74 | @Override 75 | public Long valueArrayBinaryGet(DataInput2 input, int keysLen, int pos) { 76 | input.unpackLongSkip(pos); 77 | return deserialize(input,-1); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/Serializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | import org.mapdb.io.DataInput2; 6 | import org.mapdb.io.DataInput2ByteArray; 7 | import org.mapdb.io.DataOutput2; 8 | import org.mapdb.io.DataOutput2ByteArray; 9 | 10 | import java.io.IOError; 11 | import java.io.IOException; 12 | import java.util.Comparator; 13 | 14 | /** Turns object instance into binary form and vice versa */ 15 | public interface Serializer extends Comparator { //TODO deatach comparator from serializer??? 16 | 17 | void serialize(@NotNull DataOutput2 out, @NotNull K k); 18 | 19 | K deserialize(@NotNull DataInput2 input); 20 | 21 | @Nullable Class serializedType(); 22 | 23 | default boolean equals(@Nullable K k1, @Nullable K k2){ 24 | return k1==k2 || (k1!=null && k1.equals(k2)); 25 | } 26 | 27 | 28 | default int hashCode(@NotNull K k){ 29 | return k.hashCode(); //TODO better hash 30 | } 31 | 32 | 33 | default int hashCode(@NotNull K k, int hashSeed){ 34 | return hashSeed + k.hashCode(); //TODO better mixing 35 | } 36 | 37 | default K deserialize(DataInput2 in, int i){ 38 | if(i!=-1) 39 | throw new AssertionError(); //FIXME temp method for compatibility 40 | 41 | return deserialize(in); 42 | } 43 | 44 | @Deprecated 45 | default boolean isTrusted(){ 46 | return true; 47 | } 48 | 49 | default int compare(K k1, K k2){ 50 | return ((Comparable)k1).compareTo(k2); //TODO comparators 51 | } 52 | 53 | default int fixedSize() { 54 | return -1; 55 | } 56 | 57 | /** Creates binary copy of given object. If the datatype is immutable the same instance might be returned */ 58 | default K clone(K value){ 59 | DataOutput2 out = new DataOutput2ByteArray(); 60 | serialize(out, value); 61 | DataInput2 in2 = new DataInput2ByteArray(out.copyBytes()); 62 | return deserialize(in2); 63 | } 64 | 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/SerializerIllegalAccess.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * Created by jan on 2/28/16. 11 | */ 12 | public class SerializerIllegalAccess extends DefaultGroupSerializer { 13 | @Override 14 | public void serialize(DataOutput2 out, E value) { 15 | throw new IllegalAccessError(); 16 | } 17 | 18 | @Override 19 | public E deserialize(DataInput2 in) { 20 | throw new IllegalAccessError(); 21 | } 22 | 23 | @Nullable 24 | @Override 25 | public Class serializedType() { 26 | return Object.class; 27 | } 28 | 29 | @Override 30 | public boolean isTrusted() { 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/SerializerUtils.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.BigInteger; 5 | import java.util.Date; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import java.util.UUID; 9 | 10 | import static org.mapdb.ser.Serializers.*; 11 | /** 12 | * Created by jan on 2/28/16. 13 | */ 14 | public final class SerializerUtils { 15 | 16 | 17 | private static Map SERIALIZER_FOR_CLASS = new HashMap(); 18 | 19 | static { 20 | SERIALIZER_FOR_CLASS.put(char.class, CHAR); 21 | SERIALIZER_FOR_CLASS.put(Character.class, CHAR); 22 | SERIALIZER_FOR_CLASS.put(String.class, STRING); 23 | SERIALIZER_FOR_CLASS.put(long.class, LONG); 24 | SERIALIZER_FOR_CLASS.put(Long.class, LONG); 25 | SERIALIZER_FOR_CLASS.put(int.class, INTEGER); 26 | SERIALIZER_FOR_CLASS.put(Integer.class, INTEGER); 27 | SERIALIZER_FOR_CLASS.put(boolean.class, BOOLEAN); 28 | SERIALIZER_FOR_CLASS.put(Boolean.class, BOOLEAN); 29 | SERIALIZER_FOR_CLASS.put(byte[].class, BYTE_ARRAY); 30 | SERIALIZER_FOR_CLASS.put(char[].class, CHAR_ARRAY); 31 | SERIALIZER_FOR_CLASS.put(int[].class, INT_ARRAY); 32 | SERIALIZER_FOR_CLASS.put(long[].class, LONG_ARRAY); 33 | SERIALIZER_FOR_CLASS.put(double[].class, DOUBLE_ARRAY); 34 | SERIALIZER_FOR_CLASS.put(UUID.class, UUID); 35 | SERIALIZER_FOR_CLASS.put(byte.class, BYTE); 36 | SERIALIZER_FOR_CLASS.put(Byte.class, BYTE); 37 | SERIALIZER_FOR_CLASS.put(float.class, FLOAT); 38 | SERIALIZER_FOR_CLASS.put(Float.class, FLOAT); 39 | SERIALIZER_FOR_CLASS.put(double.class, DOUBLE); 40 | SERIALIZER_FOR_CLASS.put(Double.class, DOUBLE); 41 | SERIALIZER_FOR_CLASS.put(short.class, SHORT); 42 | SERIALIZER_FOR_CLASS.put(Short.class, SHORT); 43 | SERIALIZER_FOR_CLASS.put(short[].class, SHORT_ARRAY); 44 | SERIALIZER_FOR_CLASS.put(float[].class, FLOAT_ARRAY); 45 | SERIALIZER_FOR_CLASS.put(BigDecimal.class, BIG_DECIMAL); 46 | SERIALIZER_FOR_CLASS.put(BigInteger.class, BIG_INTEGER); 47 | SERIALIZER_FOR_CLASS.put(Class.class, CLASS); 48 | SERIALIZER_FOR_CLASS.put(Date.class, DATE); 49 | 50 | } 51 | 52 | 53 | public static Serializer serializerForClass(Class clazz){ 54 | return SERIALIZER_FOR_CLASS.get(clazz); 55 | } 56 | 57 | public static int compareInt(int x, int y) { 58 | return (x < y) ? -1 : ((x == y) ? 0 : 1); 59 | } 60 | 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/Serializers.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | import org.mapdb.DBException; 6 | import org.mapdb.io.DataInput2; 7 | import org.mapdb.io.DataInput2ByteArray; 8 | import org.mapdb.io.DataOutput2; 9 | import org.mapdb.io.DataOutput2ByteArray; 10 | 11 | import java.io.*; 12 | import java.math.BigDecimal; 13 | import java.math.BigInteger; 14 | import java.util.*; 15 | 16 | public final class Serializers { 17 | 18 | private Serializers(){} 19 | 20 | 21 | /** Serializer for [java.lang.Integer] */ 22 | public static final Serializer INTEGER = new IntegerSerializer(); 23 | 24 | /** Serializer for [java.lang.Long] */ 25 | public static final Serializer LONG = new LongSerializer(); 26 | 27 | 28 | /** Serializer for recids (packed 6 bytes, extra parity bit) */ 29 | public static final Serializer RECID = new RecidSerializer(); 30 | 31 | /** Serializer for [java.lang.String] */ 32 | public static final Serializer STRING = new StringSerializer(); 33 | 34 | public static final Serializer STRING_DELTA = new StringDeltaSerializer(); 35 | 36 | public static final Serializer STRING_DELTA2 = new StringDelta2Serializer(); 37 | 38 | 39 | public static final Serializer STRING_NOSIZE = new StringNoSizeSerializer(); 40 | 41 | 42 | /** 43 | * Serializer for `byte[]`, but does not add extra bytes for array size. 44 | * 45 | * Uses [org.mapdb.io.DataInput2.available] to determine array size on deserialization. 46 | */ 47 | public static final Serializer BYTE_ARRAY_NOSIZE = new ByteArrayNoSizeSerializer(); 48 | 49 | 50 | 51 | public static final Serializer JAVA = new JavaSerializer(); 52 | 53 | public static final Serializer BYTE = new ByteSerializer(); 54 | 55 | /** Serializer for `byte[]`, adds extra few bytes for array size */ 56 | public static final Serializer BYTE_ARRAY = new ByteArraySerializer(); 57 | public static final Serializer BYTE_ARRAY_DELTA = new ByteArrayDeltaSerializer(); 58 | public static final Serializer BYTE_ARRAY_DELTA2 = new ByteArrayDelta2Serializer(); 59 | 60 | 61 | public static final Serializer CHAR = new CharSerializer(); 62 | public static final Serializer CHAR_ARRAY = new CharArraySerializer(); 63 | 64 | public static final Serializer SHORT = new ShortSerializer(); 65 | public static final Serializer SHORT_ARRAY = new ShortArraySerializer(); 66 | 67 | public static final Serializer FLOAT = new FloatSerializer(); 68 | public static final Serializer FLOAT_ARRAY = new FloatArraySerializer(); 69 | 70 | public static final Serializer DOUBLE = new DoubleSerializer(); 71 | public static final Serializer DOUBLE_ARRAY = new DoubleArraySerializer(); 72 | 73 | public static final Serializer BOOLEAN = new BooleanSerializer(); 74 | 75 | public static final Serializer INT_ARRAY = new IntArraySerializer(); 76 | public static final Serializer LONG_ARRAY = new LongArraySerializer(); 77 | 78 | 79 | public static final Serializer BIG_DECIMAL = new BigDecimalSerializer(); 80 | public static final Serializer BIG_INTEGER = new BigIntegerSerializer(); 81 | 82 | public static final Serializer CLASS = new ClassSerializer(); 83 | public static final Serializer DATE = new DateSerializer(); 84 | public static final Serializer UUID = new UUIDSerializer(); 85 | 86 | 87 | public static byte[] serializeToByteArray(R record, Serializer serializer) { 88 | DataOutput2ByteArray out = new DataOutput2ByteArray(); 89 | serializer.serialize(out,record); 90 | return out.copyBytes(); 91 | } 92 | 93 | @Nullable 94 | public static R clone(@NotNull R r, @NotNull Serializer ser) { 95 | byte[] b = serializeToByteArray(r, ser); 96 | return ser.deserialize(new DataInput2ByteArray(b)); 97 | } 98 | 99 | @NotNull 100 | public static boolean binaryEqual(@NotNull Serializer ser, Object a, Object b) { 101 | if(a==b) 102 | return true; 103 | if(a==null || b==null) 104 | return false; 105 | byte[] ba = serializeToByteArray(a, ser); 106 | byte[] bb = serializeToByteArray(b, ser); 107 | return Arrays.equals(ba,bb); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/ShortArraySerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class ShortArraySerializer extends DefaultGroupSerializer { 14 | @Override 15 | public void serialize(DataOutput2 out, short[] value) { 16 | out.packInt(value.length); 17 | for (short v : value) { 18 | out.writeShort(v); 19 | } 20 | } 21 | 22 | @Override 23 | public short[] deserialize(DataInput2 in) { 24 | short[] ret = new short[in.unpackInt()]; 25 | for (int i = 0; i < ret.length; i++) { 26 | ret[i] = in.readShort(); 27 | } 28 | return ret; 29 | } 30 | 31 | @Nullable 32 | @Override 33 | public Class serializedType() { 34 | return short[].class; 35 | } 36 | 37 | @Override 38 | public boolean isTrusted() { 39 | return true; 40 | } 41 | 42 | @Override 43 | public boolean equals(short[] a1, short[] a2) { 44 | return Arrays.equals(a1, a2); 45 | } 46 | 47 | @Override 48 | public int hashCode(short[] shorts, int seed) { 49 | for (short element : shorts) 50 | seed = (-1640531527) * seed + element; 51 | return seed; 52 | } 53 | 54 | @Override 55 | public int compare(short[] o1, short[] o2) { 56 | if (o1 == o2) return 0; 57 | final int len = Math.min(o1.length, o2.length); 58 | for (int i = 0; i < len; i++) { 59 | if (o1[i] == o2[i]) 60 | continue; 61 | if (o1[i] > o2[i]) 62 | return 1; 63 | return -1; 64 | } 65 | return SerializerUtils.compareInt(o1.length, o2.length); 66 | } 67 | 68 | @Override 69 | public short[] nextValue(short[] value) { 70 | value = value.clone(); 71 | 72 | for (int i = value.length-1; ;i--) { 73 | short b1 = value[i]; 74 | if(b1==Short.MAX_VALUE){ 75 | if(i==0) 76 | return null; 77 | value[i]=Short.MIN_VALUE; 78 | continue; 79 | } 80 | value[i] = (short) (b1+1); 81 | return value; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/ShortSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * Created by jan on 2/28/16. 11 | */ 12 | public class ShortSerializer extends DefaultGroupSerializer { 13 | @Override 14 | public void serialize(DataOutput2 out, Short value) { 15 | out.writeShort(value.shortValue()); 16 | } 17 | 18 | @Override 19 | public Short deserialize(DataInput2 in) { 20 | return in.readShort(); 21 | } 22 | 23 | @Nullable 24 | @Override 25 | public Class serializedType() { 26 | return Short.class; 27 | } 28 | 29 | //TODO value array operations 30 | 31 | @Override 32 | public int fixedSize() { 33 | return 2; 34 | } 35 | 36 | @Override 37 | public boolean isTrusted() { 38 | return true; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/StringAsciiSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | import org.mapdb.io.DataInput2; 6 | import org.mapdb.io.DataOutput2; 7 | 8 | import java.io.IOException; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class StringAsciiSerializer extends DefaultGroupSerializer { 14 | @Override 15 | public void serialize(DataOutput2 out, String value) { 16 | int size = value.length(); 17 | out.packInt(size); 18 | for (int i = 0; i < size; i++) { 19 | out.write(value.charAt(i)); 20 | } 21 | } 22 | 23 | @Override 24 | public String deserialize(DataInput2 in) { 25 | int size = in.unpackInt(); 26 | StringBuilder result = new StringBuilder(size); 27 | for (int i = 0; i < size; i++) { 28 | result.append((char) in.readUnsignedByte()); 29 | } 30 | return result.toString(); 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public Class serializedType() { 36 | return String.class; 37 | } 38 | 39 | @Override 40 | public boolean isTrusted() { 41 | return true; 42 | } 43 | 44 | @Override 45 | public int hashCode(@NotNull String s, int seed) { 46 | return Serializers.STRING.hashCode(s, seed); 47 | } 48 | 49 | // @Override 50 | // public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) { 51 | // if(comparator!=null && comparator!=Fun.COMPARATOR) { 52 | // return super.getBTreeKeySerializer(comparator); 53 | // } 54 | // return BTreeKeySerializer.STRING; //PERF ascii specific serializer? 55 | // } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/StringDeltaSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.mapdb.io.DataIO; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * Created by jan on 2/29/16. 11 | */ 12 | public class StringDeltaSerializer extends StringSerializer{ 13 | 14 | 15 | protected static int commonPrefixLen(char[][] chars) { 16 | //$DELAY$ 17 | for(int ret=0;;ret++){ 18 | if(chars[0].length==ret) { 19 | return ret; 20 | } 21 | char byt = chars[0][ret]; 22 | for(int i=1;i { 14 | @Override 15 | public void serialize(DataOutput2 out, String value) { 16 | out.writeUTF(value); 17 | } 18 | 19 | @Override 20 | public String deserialize(DataInput2 in) { 21 | return in.readUTF().intern(); 22 | } 23 | 24 | @Nullable 25 | @Override 26 | public Class serializedType() { 27 | return String.class; 28 | } 29 | 30 | @Override 31 | public boolean isTrusted() { 32 | return true; 33 | } 34 | 35 | @Override 36 | public int hashCode(@NotNull String s, int seed) { 37 | return Serializers.STRING.hashCode(s, seed); 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/StringNoSizeSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | import org.mapdb.io.DataInput2; 6 | import org.mapdb.io.DataOutput2; 7 | 8 | import java.io.IOException; 9 | 10 | public class StringNoSizeSerializer implements Serializer { 11 | 12 | @Override 13 | public void serialize(@NotNull DataOutput2 out, @NotNull String s) { 14 | out.writeUTF(s); 15 | } 16 | 17 | @Override 18 | public String deserialize(@NotNull DataInput2 input) { 19 | return input.readUTF(); 20 | } 21 | 22 | @Override 23 | public @Nullable Class serializedType() { 24 | return String.class; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/StringOrigHashSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.mapdb.io.DataIO; 5 | import org.mapdb.io.DataInput2; 6 | import org.mapdb.io.DataOutput2; 7 | 8 | import java.io.IOException; 9 | 10 | /** 11 | * Created by jan on 2/28/16. 12 | */ 13 | public class StringOrigHashSerializer extends StringSerializer { 14 | @Override 15 | public void serialize(DataOutput2 out, String value) { 16 | out.writeUTF(value); 17 | } 18 | 19 | @Override 20 | public String deserialize(DataInput2 in, int available) { 21 | return in.readUTF(); 22 | } 23 | 24 | @Override 25 | public boolean isTrusted() { 26 | return true; 27 | } 28 | 29 | 30 | // @Override 31 | // public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) { 32 | // if(comparator!=null && comparator!=Fun.COMPARATOR) { 33 | // return super.getBTreeKeySerializer(comparator); 34 | // } 35 | // return BTreeKeySerializer.STRING; 36 | // } 37 | 38 | 39 | @Override 40 | public int hashCode(@NotNull String s, int seed) { 41 | return DataIO.intHash(s.hashCode() + seed); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/ser/StringSerializer.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.mapdb.io.DataInput2; 5 | import org.mapdb.io.DataOutput2; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | import java.util.Comparator; 10 | 11 | public class StringSerializer implements GroupSerializer { 12 | 13 | @Override 14 | public void serialize(DataOutput2 out, String value) { 15 | out.writeUTF(value); 16 | } 17 | 18 | @Override 19 | public String deserialize(DataInput2 in) { 20 | return in.readUTF(); 21 | } 22 | 23 | @Nullable 24 | @Override 25 | public Class serializedType() { 26 | return String.class; 27 | } 28 | 29 | @Override 30 | public boolean isTrusted() { 31 | return true; 32 | } 33 | 34 | 35 | @Override 36 | public void valueArraySerialize(DataOutput2 out2, char[][] vals) { 37 | for(char[] v:(char[][])vals){ 38 | out2.packInt(v.length); 39 | for(char c:v){ 40 | out2.packInt(c); 41 | } 42 | } 43 | } 44 | 45 | @Override 46 | public char[][] valueArrayDeserialize(DataInput2 in2, int size) { 47 | char[][] ret = new char[size][]; 48 | for(int i=0;i>> 1; 73 | int compare = comparator.compare(key, new String(array[mid])); 74 | 75 | if (compare == 0) 76 | return mid; 77 | else if (compare < 0) 78 | hi = mid - 1; 79 | else 80 | lo = mid + 1; 81 | } 82 | return -(lo + 1); 83 | } 84 | 85 | @Override 86 | public String valueArrayGet(char[][] vals, int pos) { 87 | return new String(((char[][])vals)[pos]); 88 | } 89 | 90 | @Override 91 | public int valueArraySize(char[][] vals) { 92 | return ((char[][])vals).length; 93 | } 94 | 95 | @Override 96 | public char[][] valueArrayEmpty() { 97 | return new char[0][]; 98 | } 99 | 100 | @Override 101 | public char[][] valueArrayPut(char[][] vals, int pos, String newValue) { 102 | char[][] array = (char[][]) vals; 103 | final char[][] ret = Arrays.copyOf(array, array.length+1); 104 | if(pos { 16 | @Override 17 | public void serialize(DataOutput2 out, UUID value) { 18 | out.writeLong(value.getMostSignificantBits()); 19 | out.writeLong(value.getLeastSignificantBits()); 20 | } 21 | 22 | @Override 23 | public UUID deserialize(DataInput2 in) { 24 | return new UUID(in.readLong(), in.readLong()); 25 | } 26 | 27 | @Nullable 28 | @Override 29 | public Class serializedType() { 30 | return UUID.class; 31 | } 32 | 33 | @Override 34 | public int fixedSize() { 35 | return 16; 36 | } 37 | 38 | @Override 39 | public boolean isTrusted() { 40 | return true; 41 | } 42 | 43 | 44 | @Override 45 | public int hashCode(UUID uuid, int seed) { 46 | //on java6 uuid.hashCode is not thread safe. This is workaround 47 | long a = uuid.getLeastSignificantBits() ^ uuid.getMostSignificantBits(); 48 | return ((int) (a >> 32)) ^ (int) a; 49 | 50 | } 51 | 52 | 53 | @Override 54 | public int valueArraySearch(long[] keys, UUID key) { 55 | return Arrays.binarySearch(valueArrayToArray(keys), key); //TODO search 56 | } 57 | 58 | @Override 59 | public int valueArraySearch(long[] keys, UUID key, Comparator comparator) { 60 | return Arrays.binarySearch(valueArrayToArray(keys), key, comparator); //TODO search 61 | } 62 | 63 | @Override 64 | public void valueArraySerialize(DataOutput2 out, long[] vals) { 65 | for (long o : (long[]) vals) { 66 | out.writeLong(o); 67 | } 68 | } 69 | 70 | @Override 71 | public long[] valueArrayDeserialize(DataInput2 in, int size) { 72 | size *= 2; 73 | long[] ret = new long[size]; 74 | for (int i = 0; i < size; i++) { 75 | ret[i] = in.readLong(); 76 | } 77 | return ret; 78 | } 79 | 80 | @Override 81 | public UUID valueArrayGet(long[] v, int pos) { 82 | pos *= 2; 83 | return new UUID(v[pos++], v[pos]); 84 | } 85 | 86 | @Override 87 | public int valueArraySize(long[] vals) { 88 | return vals.length / 2; 89 | } 90 | 91 | @Override 92 | public long[] valueArrayEmpty() { 93 | return new long[0]; 94 | } 95 | 96 | @Override 97 | public long[] valueArrayPut(long[] vals, int pos, UUID newValue) { 98 | pos *= 2; 99 | 100 | long[] array = (long[]) vals; 101 | final long[] ret = Arrays.copyOf(array, array.length + 2); 102 | 103 | if (pos < array.length) { 104 | System.arraycopy(array, pos, ret, pos + 2, array.length - pos); 105 | } 106 | ret[pos++] = newValue.getMostSignificantBits(); 107 | ret[pos] = newValue.getLeastSignificantBits(); 108 | return ret; 109 | } 110 | 111 | @Override 112 | public long[] valueArrayUpdateVal(long[] vals, int pos, UUID newValue) { 113 | pos *= 2; 114 | long[] vals2 = ((long[]) vals).clone(); 115 | vals2[pos++] = newValue.getMostSignificantBits(); 116 | vals2[pos] = newValue.getLeastSignificantBits(); 117 | return vals2; 118 | } 119 | 120 | 121 | @Override 122 | public long[] valueArrayFromArray(Object[] objects) { 123 | long[] ret = new long[objects.length * 2]; 124 | int pos = 0; 125 | 126 | for (Object o : objects) { 127 | UUID uuid = (java.util.UUID) o; 128 | ret[pos++] = uuid.getMostSignificantBits(); 129 | ret[pos++] = uuid.getLeastSignificantBits(); 130 | } 131 | 132 | return ret; 133 | } 134 | 135 | @Override 136 | public long[] valueArrayCopyOfRange(long[] vals, int from, int to) { 137 | return Arrays.copyOfRange((long[]) vals, from * 2, to * 2); 138 | } 139 | 140 | @Override 141 | public long[] valueArrayDeleteValue(long[] vals, int pos) { 142 | pos *= 2; 143 | long[] valsOrig = (long[]) vals; 144 | long[] vals2 = new long[valsOrig.length - 2]; 145 | System.arraycopy(vals, 0, vals2, 0, pos - 2); 146 | System.arraycopy(vals, pos, vals2, pos - 2, vals2.length - (pos - 2)); 147 | return vals2; 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/FileHeapBufStore.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.store; 2 | 3 | import org.mapdb.util.IO; 4 | 5 | import java.io.*; 6 | 7 | public class FileHeapBufStore extends HeapBufStore{ 8 | 9 | protected final File file; 10 | 11 | //-newRWLOCK 12 | 13 | public FileHeapBufStore(File file) { 14 | this.file = file; 15 | 16 | //-WLOCK 17 | reload(); 18 | //-WUNLOCK 19 | } 20 | 21 | protected void reload() { 22 | //-AWLOCKED 23 | clear(); 24 | 25 | try(DataInputStream is = new DataInputStream(new FileInputStream(file))) { 26 | long maxRecid = 0; 27 | 28 | //load records 29 | long recCount = IO.readLong(is); 30 | for(long i=0;i{ 61 | try { 62 | IO.writeLong(out, recid); 63 | int size = buf==PREALLOC_RECORD? -1 : buf.length; 64 | IO.writeInt(out, size); 65 | if(size>0) 66 | IO.writeByteArray(out, buf); 67 | }catch(IOException e){ 68 | throw new IOError(e); 69 | } 70 | }); 71 | 72 | out.flush(); 73 | } catch (FileNotFoundException e) { 74 | throw new IOError(e); //file could not be created 75 | } catch (IOException e) { 76 | throw new IOError(e); 77 | } 78 | } 79 | public void close() { 80 | //-WLOCK 81 | save(); 82 | //-WUNLOCK 83 | } 84 | 85 | private void clear() { 86 | //-AWLOCK 87 | freeRecids.clear(); 88 | freeRecids.trimToSize(); 89 | records.clear(); 90 | records.compact(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/ReadonlyStore.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.store; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.mapdb.ser.Serializer; 5 | 6 | import java.io.Closeable; 7 | 8 | public interface ReadonlyStore extends Closeable { 9 | 10 | 11 | /** 12 | * Get existing record 13 | * 14 | * @return record or null if record was not allocated yet, or was deleted 15 | **/ 16 | @NotNull K get(long recid, @NotNull Serializer ser); 17 | 18 | void close(); 19 | 20 | /** 21 | * Iterates over all records in store. 22 | * 23 | * Function takes recid and binary data 24 | */ 25 | void getAll(@NotNull GetAllCallback callback); 26 | 27 | interface GetAllCallback{ 28 | void takeOne(long recid, @NotNull byte[] data); 29 | } 30 | 31 | /** 32 | * Returns true if store does not contain any data and no recids were allocated yet. 33 | * Store is usually empty just after creation. 34 | */ 35 | boolean isEmpty(); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/Recids.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.store; 2 | 3 | public class Recids { 4 | 5 | public static final long RECID_NAME_PARAMS = 1L; 6 | 7 | public static final long RECID_MAX_RESERVED = 255L; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/Store.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.store; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.mapdb.ser.Serializer; 5 | 6 | public interface Store extends ReadonlyStore{ 7 | 8 | 9 | /** allocates new null record, and returns its recid. It can be latter updated with `updateAtomic()` or `cas` */ 10 | long preallocate(); 11 | 12 | void preallocatePut(long recid, @NotNull Serializer serializer, @NotNull R record); 13 | 14 | default void preallocate(long[] recids) { 15 | for(int i=0;i long put(@NotNull R record, @NotNull Serializer serializer); 22 | 23 | /** updateAtomic existing record with new value */ 24 | void update(long recid, @NotNull Serializer serializer, @NotNull R updatedRecord); 25 | 26 | 27 | @NotNull default R getAndUpdate(long recid, @NotNull Serializer serializer, @NotNull R updatedRecord) { 28 | R old = get(recid,serializer); 29 | update(recid, serializer, updatedRecord); 30 | return old; //TODO atomic 31 | 32 | } 33 | 34 | void verify(); 35 | 36 | void commit(); 37 | 38 | void compact(); 39 | 40 | boolean isThreadSafe(); 41 | 42 | 43 | 44 | 45 | interface Transform{ 46 | @NotNull R transform(@NotNull R r); 47 | } 48 | 49 | @NotNull default R updateAndGet(long recid, @NotNull Serializer serializer, @NotNull Transform t) { 50 | R old = get(recid,serializer); 51 | R newRec = t.transform(old); 52 | update(recid, serializer, newRec); 53 | return newRec; //TODO atomic 54 | } 55 | 56 | @NotNull default R getAndUpdateAtomic(long recid, @NotNull Serializer serializer, @NotNull Transform t) { 57 | R old = get(recid,serializer); 58 | R newRec = t.transform(old); 59 | update(recid, serializer, newRec); 60 | return old; //TODO atomic 61 | } 62 | 63 | 64 | void updateAtomic(long recid, @NotNull Serializer serializer, @NotNull Transform r); 65 | 66 | /** atomically compares and swap records 67 | * @return true if compare was sucessfull and record was swapped, else false 68 | */ 69 | boolean compareAndUpdate(long recid, @NotNull Serializer serializer, @NotNull R expectedOldRecord, @NotNull R updatedRecord); 70 | 71 | boolean compareAndDelete(long recid, @NotNull Serializer serializer, @NotNull R expectedOldRecord); 72 | 73 | /** delete existing record */ 74 | void delete(long recid, @NotNull Serializer serializer); 75 | 76 | @NotNull R getAndDelete(long recid, @NotNull Serializer serializer); 77 | 78 | default int maxRecordSize() { 79 | return Integer.MAX_VALUE; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/StoreTx.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.store; 2 | 3 | public interface StoreTx extends Store { 4 | void commit(); 5 | void rollback(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/legacy/DataInput2Exposed.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.store.legacy; 2 | 3 | import org.mapdb.io.DataInput2; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | /** DataInput on top of {@code byte[]} */ 8 | public final class DataInput2Exposed implements DataInput2 { 9 | 10 | protected final ByteBuffer buf; 11 | protected int pos; 12 | 13 | public DataInput2Exposed(ByteBuffer b) { 14 | this(b, 0); 15 | } 16 | 17 | public DataInput2Exposed(ByteBuffer bb, int pos) { 18 | buf = bb; 19 | this.pos = pos; 20 | } 21 | 22 | public int getPos(){ 23 | return pos; 24 | } 25 | 26 | @Override 27 | public void readFully(byte[] b, int off, int len) { 28 | ByteBuffer clone = buf.duplicate(); 29 | clone.position(pos); 30 | pos+=len; 31 | clone.get(b,off,len); 32 | } 33 | 34 | @Override 35 | public int skipBytes(final int n) { 36 | pos += n; 37 | return n; 38 | } 39 | 40 | @Override 41 | public boolean readBoolean() { 42 | return buf.get(pos++) ==1; 43 | } 44 | 45 | @Override 46 | public byte readByte() { 47 | return buf.get(pos++); 48 | } 49 | 50 | @Override 51 | public int readUnsignedByte() { 52 | return buf.get(pos++)& 0xff; 53 | } 54 | 55 | @Override 56 | public short readShort() { 57 | final short ret = buf.getShort(pos); 58 | pos+=2; 59 | return ret; 60 | } 61 | 62 | @Override 63 | public char readChar() { 64 | final char ret = buf.getChar(pos); 65 | pos+=2; 66 | return ret; 67 | } 68 | 69 | @Override 70 | public int readInt() { 71 | final int ret = buf.getInt(pos); 72 | pos+=4; 73 | return ret; 74 | } 75 | 76 | @Override 77 | public long readLong() { 78 | final long ret = buf.getLong(pos); 79 | pos+=8; 80 | return ret; 81 | } 82 | 83 | 84 | @Override 85 | public int available() { 86 | return buf.limit()-pos; 87 | } 88 | 89 | @Override 90 | public boolean availableMore() { 91 | return available()>0; 92 | } 93 | 94 | @Override 95 | public int readPackedInt() { 96 | return readInt(); 97 | } 98 | 99 | @Override 100 | public long readPackedLong() { 101 | return readLong(); 102 | } 103 | 104 | 105 | @Override 106 | public void unpackLongSkip(int count) { 107 | int pos2 = this.pos; 108 | while(count>0){ 109 | // count -= (b[pos2++]&0x80)>>7; 110 | //TODO go back to packed longs, remove code bellow 111 | readLong(); 112 | count--; 113 | pos2+=8; 114 | } 115 | this.pos = pos2; 116 | } 117 | 118 | } 119 | 120 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/legacy/Fun.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.store.legacy; 2 | 3 | public class Fun { 4 | public static long roundUp(long number, long roundUpToMultipleOf) { 5 | return ((number+roundUpToMultipleOf-1)/(roundUpToMultipleOf))*roundUpToMultipleOf; 6 | } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/legacy/LongMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jan Kotek 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.mapdb.store.legacy; 18 | 19 | import java.util.Iterator; 20 | 21 | /** 22 | * Same as 'java.util.Map' but uses primitive 'long' keys to minimise boxing (and GC) overhead. 23 | * 24 | * @author Jan Kotek 25 | */ 26 | public abstract class LongMap { 27 | 28 | /** 29 | * Removes all mappings from this hash map, leaving it empty. 30 | * 31 | * @see #isEmpty 32 | * @see #size 33 | */ 34 | public abstract void clear(); 35 | 36 | /** 37 | * Returns the value of the mapping with the specified key. 38 | * 39 | * @param key the key. 40 | * @return the value of the mapping with the specified key, or {@code null} 41 | * if no mapping for the specified key is found. 42 | */ 43 | public abstract V get(long key); 44 | 45 | /** 46 | * Returns whether this map is empty. 47 | * 48 | * @return {@code true} if this map has no elements, {@code false} 49 | * otherwise. 50 | * @see #size() 51 | */ 52 | public abstract boolean isEmpty(); 53 | 54 | /** 55 | * Maps the specified key to the specified value. 56 | * 57 | * @param key the key. 58 | * @param value the value. 59 | * @return the value of any previous mapping with the specified key or 60 | * {@code null} if there was no such mapping. 61 | */ 62 | public abstract V put(long key, V value); 63 | 64 | 65 | /** 66 | * Removes the mapping from this map 67 | * 68 | * @param key to remove 69 | * @return value contained under this key, or null if value did not exist 70 | */ 71 | public abstract V remove(long key); 72 | 73 | /** 74 | * Returns the number of elements in this map. 75 | * 76 | * @return the number of elements in this map. 77 | */ 78 | public abstract int size(); 79 | 80 | 81 | /** 82 | * @return iterator over values in map 83 | */ 84 | public abstract Iterator valuesIterator(); 85 | 86 | public abstract LongMapIterator longMapIterator(); 87 | 88 | 89 | /** Iterates over LongMap key and values without boxing long keys */ 90 | public interface LongMapIterator{ 91 | boolean moveToNext(); 92 | long key(); 93 | V value(); 94 | 95 | void remove(); 96 | } 97 | 98 | @Override 99 | public String toString(){ 100 | final StringBuilder b = new StringBuilder(); 101 | b.append(getClass().getSimpleName()); 102 | b.append('['); 103 | boolean first = true; 104 | LongMapIterator iter = longMapIterator(); 105 | while(iter.moveToNext()){ 106 | if(first){ 107 | first = false; 108 | }else{ 109 | b.append(", "); 110 | } 111 | b.append(iter.key()); 112 | b.append(" => "); 113 | b.append(iter.value()); 114 | } 115 | b.append(']'); 116 | return b.toString(); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/legacy/Store2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Jan Kotek 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.mapdb.store.legacy; 17 | 18 | import org.mapdb.CC; 19 | import org.mapdb.io.DataOutput2ByteArray; 20 | import org.mapdb.ser.Serializer; 21 | import org.mapdb.ser.Serializers; 22 | import org.mapdb.store.Store; 23 | 24 | import java.io.IOException; 25 | import java.nio.ByteBuffer; 26 | import java.util.Arrays; 27 | import java.util.Iterator; 28 | import java.util.List; 29 | import java.util.concurrent.CopyOnWriteArrayList; 30 | import java.util.concurrent.locks.Lock; 31 | import java.util.concurrent.locks.ReentrantLock; 32 | import java.util.concurrent.locks.ReentrantReadWriteLock; 33 | import java.util.logging.Logger; 34 | 35 | /** 36 | * Low level record store. 37 | */ 38 | public abstract class Store2 implements Store { 39 | 40 | protected static final Logger LOG = Logger.getLogger(Store.class.getName()); 41 | 42 | public static final int VOLUME_CHUNK_SHIFT = 20; // 1 MB 43 | 44 | protected final static int CHECKSUM_FLAG_MASK = 1; 45 | protected final static int COMPRESS_FLAG_MASK = 1<<2; 46 | protected final static int ENCRYPT_FLAG_MASK = 1<<3; 47 | 48 | 49 | protected static final int CHUNK_SIZE = 1<< VOLUME_CHUNK_SHIFT; 50 | 51 | 52 | protected static final int CHUNK_SIZE_MOD_MASK = CHUNK_SIZE -1; 53 | 54 | public abstract long getMaxRecid(); 55 | public abstract ByteBuffer getRaw(long recid); 56 | public abstract Iterator getFreeRecids(); 57 | public abstract void updateRaw(long recid, ByteBuffer data); 58 | 59 | /** returns maximal store size or `0` if there is no limit */ 60 | public abstract long getSizeLimit(); 61 | 62 | /** returns current size occupied by physical store (does not include index). It means file allocated by physical file */ 63 | public abstract long getCurrSize(); 64 | 65 | /** returns free size in physical store (does not include index). */ 66 | public abstract long getFreeSize(); 67 | 68 | /** get some statistics about store. This may require traversing entire store, so it can take some time.*/ 69 | public abstract String calculateStatistics(); 70 | 71 | public void printStatistics(){ 72 | System.out.println(calculateStatistics()); 73 | } 74 | 75 | protected Lock serializerPojoInitLock = new ReentrantLock(); 76 | 77 | 78 | protected final ReentrantLock structuralLock = new ReentrantLock(); 79 | protected final ReentrantReadWriteLock newRecidLock = new ReentrantReadWriteLock(); 80 | protected final ReentrantReadWriteLock locks = new ReentrantReadWriteLock(); 81 | 82 | protected void lockAllWrite() { 83 | newRecidLock.writeLock().lock(); 84 | locks.writeLock().lock(); 85 | structuralLock.lock(); 86 | } 87 | 88 | protected void unlockAllWrite() { 89 | structuralLock.unlock(); 90 | locks.writeLock().unlock(); 91 | newRecidLock.writeLock().unlock(); 92 | } 93 | 94 | protected DataOutput2ByteArray serialize(A value, Serializer serializer){ 95 | if(value==null) 96 | return null; 97 | 98 | DataOutput2ByteArray out = newDataOut2(); 99 | 100 | serializer.serialize(out,value); 101 | 102 | if(out.pos>0){ 103 | 104 | if(CC.PARANOID)try{ 105 | //check that array is the same after deserialization 106 | DataInput2Exposed inp = new DataInput2Exposed(ByteBuffer.wrap(Arrays.copyOf(out.buf,out.pos))); 107 | byte[] decompress = deserialize(Serializers.BYTE_ARRAY_NOSIZE,out.pos,inp); 108 | 109 | DataOutput2ByteArray expected = newDataOut2(); 110 | serializer.serialize(expected,value); 111 | 112 | byte[] expected2 = Arrays.copyOf(expected.buf, expected.pos); 113 | //check arrays equals 114 | assert(Arrays.equals(expected2,decompress)); 115 | 116 | 117 | }catch(Exception e){ 118 | throw new RuntimeException(e); 119 | } 120 | } 121 | return out; 122 | 123 | } 124 | 125 | protected DataOutput2ByteArray newDataOut2() { 126 | return new DataOutput2ByteArray(); 127 | } 128 | 129 | 130 | protected A deserialize(Serializer serializer, int size, DataInput2Exposed di) throws IOException { 131 | 132 | int start = di.pos; 133 | 134 | A ret = serializer.deserialize(di); 135 | if(size+start>di.pos) 136 | throw new AssertionError("data were not fully read, check your serializer "); 137 | if(size+start closeListeners = new CopyOnWriteArrayList(); 147 | 148 | public void closeListenerRegister(Runnable closeListener) { 149 | closeListeners.add(closeListener); 150 | } 151 | 152 | public void closeListenerUnregister(Runnable closeListener) { 153 | closeListeners.remove(closeListener); 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/store/li/LiUtil.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.store.li; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | public final class LiUtil { 6 | 7 | public static final long R_VOID = 0L; 8 | 9 | public static final long R_PREALLOC = 1; 10 | 11 | public static final long R_SMALL = 2; 12 | public static final long R_LINKED = 3; 13 | 14 | 15 | public static void zeroOut(ByteBuffer data, long offset, int size) { 16 | int end = (int) (offset+size); 17 | for(int i = (int) offset; i>> (5*8)) & 0xFFFF); 29 | } 30 | 31 | public static int decompIndexValType(long indexVal) { 32 | return (int) (indexVal >>> (7*8)); 33 | } 34 | 35 | 36 | public static long composeIndexValSmall(int size, long page) { 37 | return (R_SMALL<< (7*8)) | 38 | (((long)size)<<(5*8)) | 39 | page; 40 | } 41 | 42 | public static final long composeRecordType(long recType){ 43 | return recType<<(7*8); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/util/Exporter.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.util; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.mapdb.io.DataOutput2ByteArray; 5 | 6 | public interface Exporter { 7 | 8 | void exportToDataOutput2(@NotNull DataOutput2ByteArray output); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/util/IO.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.util; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.DataOutputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | 8 | public class IO { 9 | 10 | public static long readLong(DataInputStream in) throws IOException { 11 | return in.readLong(); 12 | } 13 | 14 | public static int readInt(DataInputStream in) throws IOException { 15 | return in.readInt(); 16 | } 17 | 18 | public static byte[] readByteArray(InputStream is, int size) throws IOException { 19 | byte[] buf = new byte[size]; 20 | int read = is.read(buf, 0, size); 21 | if(read!=size) 22 | throw new IOException("not fully read"); //TODO read fully 23 | return buf; 24 | } 25 | 26 | public static void writeLong(DataOutputStream out, long value) throws IOException { 27 | out.writeLong(value); 28 | } 29 | 30 | public static void writeInt(DataOutputStream out, int value) throws IOException { 31 | out.writeInt(value); 32 | } 33 | 34 | public static void writeByteArray(DataOutputStream out, byte[] buf) throws IOException { 35 | out.write(buf); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/util/JavaUtils.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.util; 2 | 3 | import java.util.Comparator; 4 | 5 | public class JavaUtils { 6 | 7 | 8 | public static final Comparator COMPARABLE_COMPARATOR = new Comparator() { 9 | @Override 10 | public int compare(Comparable o1, Comparable o2) { 11 | return o1.compareTo(o2); 12 | } 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/util/MonoRef.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.util; 2 | 3 | public class MonoRef { 4 | 5 | public R ref; 6 | 7 | public MonoRef() { 8 | } 9 | 10 | public MonoRef(R ref) { 11 | this.ref = ref; 12 | } 13 | 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/aaGenTest.kt: -------------------------------------------------------------------------------- 1 | import org.junit.Test 2 | 3 | class genTest{ 4 | 5 | @Test 6 | fun main(){ 7 | AACodeGen() 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/java/harmony/Support_CollectionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package harmony; 19 | 20 | import java.util.Collection; 21 | import java.util.TreeSet; 22 | 23 | /** 24 | * @tests java.util.Collection 25 | */ 26 | public class Support_CollectionTest extends junit.framework.TestCase { 27 | 28 | Collection col; // must contain the Integers 0 to 99 29 | 30 | public Support_CollectionTest(String p1) { 31 | super(p1); 32 | } 33 | 34 | public Support_CollectionTest(String p1, Collection c) { 35 | super(p1); 36 | col = c; 37 | } 38 | 39 | 40 | public void test(){ 41 | } 42 | 43 | @Override 44 | public void runTest() { 45 | if(col==null) return; 46 | 47 | new Support_UnmodifiableCollectionTest("", col).runTest(); 48 | 49 | // setup 50 | Collection myCollection = new TreeSet(); 51 | myCollection.add(new Integer(101)); 52 | myCollection.add(new Integer(102)); 53 | myCollection.add(new Integer(103)); 54 | 55 | // add 56 | assertTrue("CollectionTest - a) add did not work", col.add(new Integer( 57 | 101))); 58 | assertTrue("CollectionTest - b) add did not work", col 59 | .contains(new Integer(101))); 60 | 61 | // remove 62 | assertTrue("CollectionTest - a) remove did not work", col 63 | .remove(new Integer(101))); 64 | assertTrue("CollectionTest - b) remove did not work", !col 65 | .contains(new Integer(101))); 66 | 67 | // addAll 68 | assertTrue("CollectionTest - a) addAll failed", col 69 | .addAll(myCollection)); 70 | assertTrue("CollectionTest - b) addAll failed", col 71 | .containsAll(myCollection)); 72 | 73 | // containsAll 74 | assertTrue("CollectionTest - a) containsAll failed", col 75 | .containsAll(myCollection)); 76 | col.remove(new Integer(101)); 77 | assertTrue("CollectionTest - b) containsAll failed", !col 78 | .containsAll(myCollection)); 79 | 80 | // removeAll 81 | assertTrue("CollectionTest - a) removeAll failed", col 82 | .removeAll(myCollection)); 83 | assertTrue("CollectionTest - b) removeAll failed", !col 84 | .removeAll(myCollection)); // should not change the colletion 85 | // the 2nd time around 86 | assertTrue("CollectionTest - c) removeAll failed", !col 87 | .contains(new Integer(102))); 88 | assertTrue("CollectionTest - d) removeAll failed", !col 89 | .contains(new Integer(103))); 90 | 91 | // retianAll 92 | col.addAll(myCollection); 93 | assertTrue("CollectionTest - a) retainAll failed", col 94 | .retainAll(myCollection)); 95 | assertTrue("CollectionTest - b) retainAll failed", !col 96 | .retainAll(myCollection)); // should not change the colletion 97 | // the 2nd time around 98 | assertTrue("CollectionTest - c) retainAll failed", col 99 | .containsAll(myCollection)); 100 | assertTrue("CollectionTest - d) retainAll failed", !col 101 | .contains(new Integer(0))); 102 | assertTrue("CollectionTest - e) retainAll failed", !col 103 | .contains(new Integer(50))); 104 | 105 | // clear 106 | col.clear(); 107 | assertTrue("CollectionTest - a) clear failed", col.isEmpty()); 108 | assertTrue("CollectionTest - b) clear failed", !col 109 | .contains(new Integer(101))); 110 | 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/test/java/harmony/Support_UnmodifiableCollectionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package harmony; 19 | 20 | import junit.framework.TestCase; 21 | 22 | import java.util.*; 23 | 24 | public class Support_UnmodifiableCollectionTest extends TestCase { 25 | 26 | Collection col; 27 | 28 | // must be a collection containing the Integers 0 to 99 (which will iterate 29 | // in order) 30 | 31 | public Support_UnmodifiableCollectionTest(String p1) { 32 | super(p1); 33 | } 34 | 35 | public Support_UnmodifiableCollectionTest(String p1, Collection c) { 36 | super(p1); 37 | col = c; 38 | } 39 | 40 | 41 | public void test(){ 42 | } 43 | 44 | @Override 45 | public void runTest() { 46 | if(col==null) return; 47 | 48 | // contains 49 | assertTrue("UnmodifiableCollectionTest - should contain 0", col 50 | .contains(new Integer(0))); 51 | assertTrue("UnmodifiableCollectionTest - should contain 50", col 52 | .contains(new Integer(50))); 53 | assertTrue("UnmodifiableCollectionTest - should not contain 100", !col 54 | .contains(new Integer(100))); 55 | 56 | // containsAll 57 | HashSet hs = new HashSet(); 58 | hs.add(new Integer(0)); 59 | hs.add(new Integer(25)); 60 | hs.add(new Integer(99)); 61 | assertTrue( 62 | "UnmodifiableCollectionTest - should contain set of 0, 25, and 99", 63 | col.containsAll(hs)); 64 | hs.add(new Integer(100)); 65 | assertTrue( 66 | "UnmodifiableCollectionTest - should not contain set of 0, 25, 99 and 100", 67 | !col.containsAll(hs)); 68 | 69 | // isEmpty 70 | assertTrue("UnmodifiableCollectionTest - should not be empty", !col 71 | .isEmpty()); 72 | 73 | // iterator 74 | Iterator it = col.iterator(); 75 | SortedSet ss = new TreeSet(); 76 | while (it.hasNext()) { 77 | ss.add(it.next()); 78 | } 79 | it = ss.iterator(); 80 | for (int counter = 0; it.hasNext(); counter++) { 81 | int nextValue = it.next().intValue(); 82 | assertTrue( 83 | "UnmodifiableCollectionTest - Iterator returned wrong value. Wanted: " 84 | + counter + " got: " + nextValue, 85 | nextValue == counter); 86 | } 87 | 88 | // size 89 | assertTrue( 90 | "UnmodifiableCollectionTest - returned wrong size. Wanted 100, got: " 91 | + col.size(), col.size() == 100); 92 | 93 | // toArray 94 | Object[] objArray; 95 | objArray = col.toArray(); 96 | for (int counter = 0; it.hasNext(); counter++) { 97 | assertTrue( 98 | "UnmodifiableCollectionTest - toArray returned incorrect array", 99 | objArray[counter] == it.next()); 100 | } 101 | 102 | // toArray (Object[]) 103 | objArray = new Object[100]; 104 | col.toArray(objArray); 105 | for (int counter = 0; it.hasNext(); counter++) { 106 | assertTrue( 107 | "UnmodifiableCollectionTest - toArray(Object) filled array incorrectly", 108 | objArray[counter] == it.next()); 109 | } 110 | 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Verifiable.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | public interface Verifiable { 4 | void verify(); 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/flat/LongBufStackTest.kt: -------------------------------------------------------------------------------- 1 | package org.mapdb.flat 2 | 3 | import io.kotlintest.shouldBe 4 | import org.junit.Test 5 | 6 | class LongBufStackTest{ 7 | 8 | @Test fun putGet(){ 9 | val stack = LongBufStack() 10 | 11 | stack.pop() shouldBe 0L 12 | 13 | val count = 1000L 14 | for(i in 1L .. count){ 15 | stack.push(i) 16 | } 17 | 18 | for( i in count downTo 0){ 19 | stack.pop() shouldBe i 20 | } 21 | 22 | stack.pop() shouldBe 0L 23 | } 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/guavaTests/GwtCompatible.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.guavaTests; 2 | 3 | public @interface GwtCompatible { 4 | } 5 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/guavaTests/Helpers.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.guavaTests; 2 | 3 | 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | 9 | public class Helpers { 10 | public static Map.Entry mapEntry(final K key, final V value) { 11 | Map m = new HashMap(); 12 | m.put(key,value); 13 | m = Collections.unmodifiableMap(m); 14 | return m.entrySet().iterator().next(); 15 | } 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/guavaTests/SortedMapInterfaceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Guava Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.mapdb.guavaTests; 18 | 19 | 20 | import java.util.Iterator; 21 | import java.util.Map.Entry; 22 | import java.util.SortedMap; 23 | 24 | import org.junit.Test; 25 | import static org.junit.Assert.*; 26 | 27 | /** 28 | * Tests representing the contract of {@link SortedMap}. Concrete subclasses of 29 | * this base class test conformance of concrete {@link SortedMap} subclasses to 30 | * that contract. 31 | * 32 | * @author Jared Levy 33 | */ 34 | @GwtCompatible 35 | public abstract class SortedMapInterfaceTest 36 | extends MapInterfaceTest { 37 | 38 | protected SortedMapInterfaceTest(boolean allowsNullKeys, 39 | boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, 40 | boolean supportsClear) { 41 | super(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove, 42 | supportsClear); 43 | } 44 | 45 | @Override protected abstract SortedMap makeEmptyMap() 46 | throws UnsupportedOperationException; 47 | 48 | @Override protected abstract SortedMap makePopulatedMap() 49 | throws UnsupportedOperationException; 50 | 51 | @Override protected SortedMap makeEitherMap() { 52 | try { 53 | return makePopulatedMap(); 54 | } catch (UnsupportedOperationException e) { 55 | return makeEmptyMap(); 56 | } 57 | } 58 | 59 | @Test public void testTailMapWriteThrough() { 60 | final SortedMap map; 61 | try { 62 | map = makePopulatedMap(); 63 | } catch (UnsupportedOperationException e) { 64 | return; 65 | } 66 | if (map.size() < 2 || !supportsPut) { 67 | return; 68 | } 69 | Iterator> iterator = map.entrySet().iterator(); 70 | Entry firstEntry = iterator.next(); 71 | Entry secondEntry = iterator.next(); 72 | K key = secondEntry.getKey(); 73 | SortedMap subMap = map.tailMap(key); 74 | V value = getValueNotInPopulatedMap(); 75 | subMap.put(key, value); 76 | // assertEquals(secondEntry.getValue(), value); 77 | assertEquals(map.get(key), value); 78 | try { 79 | subMap.put(firstEntry.getKey(), value); 80 | fail("Expected IllegalArgumentException"); 81 | } catch (IllegalArgumentException expected) { 82 | } 83 | } 84 | 85 | @Test public void testTailMapRemoveThrough() { 86 | final SortedMap map; 87 | try { 88 | map = makePopulatedMap(); 89 | } catch (UnsupportedOperationException e) { 90 | return; 91 | } 92 | int oldSize = map.size(); 93 | if (map.size() < 2 || !supportsRemove) { 94 | return; 95 | } 96 | Iterator> iterator = map.entrySet().iterator(); 97 | Entry firstEntry = iterator.next(); 98 | Entry secondEntry = iterator.next(); 99 | K key = secondEntry.getKey(); 100 | SortedMap subMap = map.tailMap(key); 101 | subMap.remove(key); 102 | assertNull(subMap.remove(firstEntry.getKey())); 103 | assertEquals(map.size(), oldSize - 1); 104 | assertFalse(map.containsKey(key)); 105 | assertEquals(subMap.size(), oldSize - 2); 106 | } 107 | 108 | @Test public void testTailMapClearThrough() { 109 | final SortedMap map; 110 | try { 111 | map = makePopulatedMap(); 112 | } catch (UnsupportedOperationException e) { 113 | return; 114 | } 115 | int oldSize = map.size(); 116 | if (map.size() < 2 || !supportsClear) { 117 | return; 118 | } 119 | Iterator> iterator = map.entrySet().iterator(); 120 | iterator.next(); // advance 121 | Entry secondEntry = iterator.next(); 122 | K key = secondEntry.getKey(); 123 | SortedMap subMap = map.tailMap(key); 124 | int subMapSize = subMap.size(); 125 | subMap.clear(); 126 | assertEquals(map.size(), oldSize - subMapSize); 127 | assertTrue(subMap.isEmpty()); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/jsr166Tests/CollectionImplementation.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.jsr166Tests;/* 2 | * Written by Doug Lea and Martin Buchholz with assistance from 3 | * members of JCP JSR-166 Expert Group and released to the public 4 | * domain, as explained at 5 | * http://creativecommons.org/publicdomain/zero/1.0/ 6 | */ 7 | 8 | import java.util.Collection; 9 | 10 | /** Allows tests to work with different Collection implementations. */ 11 | public interface CollectionImplementation { 12 | /** Returns the Collection class. */ 13 | public Class klazz(); 14 | /** Returns an empty collection. */ 15 | public Collection emptyCollection(); 16 | public Object makeElement(int i); 17 | public boolean isConcurrent(); 18 | public boolean permitsNulls(); 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/jsr166Tests/CollectionTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.jsr166Tests;/* 2 | * Written by Doug Lea and Martin Buchholz with assistance from 3 | * members of JCP JSR-166 Expert Group and released to the public 4 | * domain, as explained at 5 | * http://creativecommons.org/publicdomain/zero/1.0/ 6 | */ 7 | 8 | /** 9 | * Contains tests applicable to all Collection implementations. 10 | */ 11 | public abstract class CollectionTest extends JSR166TestCase { 12 | final CollectionImplementation impl; 13 | 14 | /** Tests are parameterized by a Collection implementation. */ 15 | CollectionTest(CollectionImplementation impl, String methodName) { 16 | super(methodName); 17 | this.impl = impl; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/jsr166Tests/LinkedBlockingDeque8Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.jsr166Tests;/* 2 | * Written by Doug Lea and Martin Buchholz with assistance from 3 | * members of JCP JSR-166 Expert Group and released to the public 4 | * domain, as explained at 5 | * http://creativecommons.org/publicdomain/zero/1.0/ 6 | */ 7 | 8 | import java.util.concurrent.BlockingDeque; 9 | import java.util.Spliterator; 10 | 11 | public abstract class LinkedBlockingDeque8Test extends JSR166TestCase { 12 | 13 | 14 | protected abstract BlockingDeque newDeque(); 15 | 16 | 17 | /** 18 | * Spliterator.getComparator always throws IllegalStateException 19 | */ 20 | public void testSpliterator_getComparator() { 21 | assertThrows(IllegalStateException.class, 22 | () -> newDeque().spliterator().getComparator()); 23 | } 24 | 25 | /** 26 | * Spliterator characteristics are as advertised 27 | */ 28 | public void testSpliterator_characteristics() { 29 | BlockingDeque q = newDeque(); 30 | Spliterator s = q.spliterator(); 31 | int characteristics = s.characteristics(); 32 | int required = Spliterator.CONCURRENT 33 | | Spliterator.NONNULL 34 | | Spliterator.ORDERED; 35 | assertEquals(required, characteristics & required); 36 | assertTrue(s.hasCharacteristics(required)); 37 | assertEquals(0, characteristics 38 | & (Spliterator.DISTINCT 39 | | Spliterator.IMMUTABLE 40 | | Spliterator.SORTED)); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/jsr166Tests/LinkedBlockingQueue8Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.jsr166Tests;/* 2 | * Written by Doug Lea and Martin Buchholz with assistance from 3 | * members of JCP JSR-166 Expert Group and released to the public 4 | * domain, as explained at 5 | * http://creativecommons.org/publicdomain/zero/1.0/ 6 | */ 7 | 8 | import java.util.concurrent.LinkedBlockingQueue; 9 | import java.util.Spliterator; 10 | 11 | public class LinkedBlockingQueue8Test extends JSR166TestCase { 12 | 13 | /** 14 | * Spliterator.getComparator always throws IllegalStateException 15 | */ 16 | public void testSpliterator_getComparator() { 17 | assertThrows(IllegalStateException.class, 18 | () -> new LinkedBlockingQueue().spliterator().getComparator()); 19 | } 20 | 21 | /** 22 | * Spliterator characteristics are as advertised 23 | */ 24 | public void testSpliterator_characteristics() { 25 | LinkedBlockingQueue q = new LinkedBlockingQueue(); 26 | Spliterator s = q.spliterator(); 27 | int characteristics = s.characteristics(); 28 | int required = Spliterator.CONCURRENT 29 | | Spliterator.NONNULL 30 | | Spliterator.ORDERED; 31 | assertEquals(required, characteristics & required); 32 | assertTrue(s.hasCharacteristics(required)); 33 | assertEquals(0, characteristics 34 | & (Spliterator.DISTINCT 35 | | Spliterator.IMMUTABLE 36 | | Spliterator.SORTED)); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/kotlin/Issue888_JavaI.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.kotlin; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public interface Issue888_JavaI { 8 | 9 | default int aa(){ 10 | return 1; 11 | } 12 | 13 | 14 | default int bb(){ 15 | return 1; 16 | } 17 | 18 | class JJ implements Issue888_JavaI { 19 | @Override 20 | public int aa() { 21 | return 2; 22 | } 23 | } 24 | 25 | 26 | 27 | class JK implements Issue888_KotlinI { 28 | @Override 29 | public int aa() { 30 | return 2; 31 | } 32 | 33 | @Test public void test_override(){ 34 | assertEquals(new JJ().aa(), 2); 35 | assertEquals(new JK().aa(), 2); 36 | assertEquals(new KJ().aa(), 2); 37 | assertEquals(new KK().aa(), 2); 38 | } 39 | 40 | 41 | @Test public void test_not_override(){ 42 | assertEquals(new JJ().bb(), 1); 43 | assertEquals(new JK().bb(), 1); 44 | assertEquals(new KJ().bb(), 1); 45 | assertEquals(new KK().bb(), 1); 46 | } 47 | 48 | 49 | //See Issue 888, if this is removed, compilation fails 50 | // for now we define all interfaces in java 51 | @Override 52 | public int bb() { 53 | return 1; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/kotlin/Issue888_KotlinI.kt: -------------------------------------------------------------------------------- 1 | package org.mapdb.kotlin 2 | 3 | import org.junit.Assert.assertEquals 4 | import org.junit.Test 5 | 6 | interface Issue888_KotlinI{ 7 | 8 | fun aa(): Int { 9 | return 1 10 | } 11 | 12 | 13 | //@JvmDefault 14 | fun bb(): Int { 15 | return 1 16 | } 17 | 18 | 19 | 20 | class KJ : Issue888_JavaI { 21 | override fun aa(): Int { 22 | return 2 23 | } 24 | } 25 | 26 | 27 | class KK : Issue888_KotlinI { 28 | override fun aa(): Int { 29 | return 2 30 | } 31 | } 32 | 33 | 34 | class Test2(){ 35 | @Test 36 | fun test_override(){ 37 | assertEquals(Issue888_JavaI.JJ().aa().toLong(), 2) 38 | assertEquals(Issue888_JavaI.JK().aa().toLong(), 2) 39 | assertEquals(KJ().aa().toLong(), 2) 40 | assertEquals(KK().aa().toLong(), 2) 41 | } 42 | 43 | 44 | @Test 45 | fun test_not_override() { 46 | assertEquals(Issue888_JavaI.JJ().bb(), 1) 47 | assertEquals(Issue888_JavaI.JK().bb().toLong(), 1) 48 | assertEquals(Issue888_KotlinI.KJ().bb(), 1) 49 | assertEquals(Issue888_KotlinI.KK().bb().toLong(), 1) 50 | } 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/kotlin/Issue888_serializer_override.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.kotlin; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.junit.Test; 5 | import org.mapdb.io.DataInput2; 6 | import org.mapdb.io.DataOutput2; 7 | import org.mapdb.ser.Serializer; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | public class Issue888_serializer_override { 12 | 13 | 14 | static class AlternateHashSer implements Serializer { 15 | @Override 16 | public int hashCode(Integer integer) { 17 | return -integer; 18 | } 19 | 20 | @Override 21 | public void serialize(@NotNull DataOutput2 out, Integer integer) { 22 | 23 | } 24 | 25 | @Override 26 | public Integer deserialize(@NotNull DataInput2 input) { 27 | return null; 28 | } 29 | 30 | @Override 31 | public Class serializedType() { 32 | return Integer.class; 33 | } 34 | } 35 | 36 | @Test public void ser_default_override(){ 37 | assertEquals(-10, new AlternateHashSer().hashCode(10)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/list/KernelListHarmonyTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.list; 2 | 3 | import harmony.ArrayListTest; 4 | import org.mapdb.ser.Serializers; 5 | import org.mapdb.store.HeapBufStore; 6 | import org.mapdb.store.Store; 7 | 8 | import java.util.List; 9 | 10 | 11 | public class KernelListHarmonyTest extends ArrayListTest { 12 | 13 | @Override 14 | public List newList() { 15 | Store store = new HeapBufStore(); 16 | return (List) KernelList.Maker 17 | .newList(store, Serializers.JAVA) 18 | .entryStore(new HeapBufStore()) 19 | .make(); 20 | } 21 | 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/list/MonolithListHarmonyTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.list; 2 | 3 | import harmony.ArrayListTest; 4 | import org.mapdb.ser.Serializers; 5 | import org.mapdb.store.HeapBufStore; 6 | import org.mapdb.store.Store; 7 | 8 | import java.util.List; 9 | 10 | 11 | //TODO this test is slow, move to longtest 12 | public class MonolithListHarmonyTest extends ArrayListTest { 13 | 14 | @Override 15 | public List newList() { 16 | Store store = new HeapBufStore(); 17 | return (List) MonolithList.Maker 18 | .newList(store, Serializers.JAVA) 19 | .make(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/record/BooleanRecordTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Written by Doug Lea with assistance from members of JCP JSR-166 3 | * Expert Group and released to the public domain, as explained at 4 | * http://creativecommons.org/licenses/publicdomain 5 | * Other contributors include Andrew Wright, Jeffrey Hayes, 6 | * Pat Fisher, Mike Judd. 7 | */ 8 | package org.mapdb.record; 9 | 10 | import junit.framework.TestCase; 11 | import org.mapdb.db.DB; 12 | 13 | public class BooleanRecordTest extends TestCase{ 14 | 15 | DB db; 16 | BooleanRecord ai; 17 | 18 | @Override 19 | protected void setUp() throws Exception { 20 | db = DB.Maker.memoryDB().make(); 21 | ai= new BooleanRecord.Maker(db, "test").init(true).make(); 22 | } 23 | 24 | @Override 25 | protected void tearDown() throws Exception { 26 | db.close(); 27 | } 28 | 29 | 30 | /* 31 | * constructor initializes to given value 32 | */ 33 | public void testConstructor() { 34 | assertEquals(true,ai.get()); 35 | } 36 | 37 | /* 38 | * default constructed initializes to false 39 | */ 40 | public void testConstructor2() { 41 | BooleanRecord ai = new BooleanRecord.Maker(db, "test2").make(); 42 | assertEquals(false,ai.get()); 43 | } 44 | 45 | /* 46 | * get returns the last value set 47 | */ 48 | public void testGetSet() { 49 | 50 | assertEquals(true,ai.get()); 51 | ai.set(false); 52 | assertEquals(false,ai.get()); 53 | ai.set(true); 54 | assertEquals(true,ai.get()); 55 | 56 | } 57 | 58 | /* 59 | * compareAndSet succeeds in changing value if equal to expected else fails 60 | */ 61 | public void testCompareAndSet() { 62 | 63 | assertTrue(ai.compareAndSet(true,false)); 64 | assertEquals(false,ai.get()); 65 | assertTrue(ai.compareAndSet(false,false)); 66 | assertEquals(false,ai.get()); 67 | assertFalse(ai.compareAndSet(true,false)); 68 | assertFalse((ai.get())); 69 | assertTrue(ai.compareAndSet(false,true)); 70 | assertEquals(true,ai.get()); 71 | } 72 | 73 | /* 74 | * compareAndSet in one thread enables another waiting for value 75 | * to succeed 76 | */ 77 | public void testCompareAndSetInMultipleThreads() throws InterruptedException { 78 | Thread t = new Thread(new Runnable() { 79 | public void run() { 80 | while(!ai.compareAndSet(false, true)) Thread.yield(); 81 | }}); 82 | 83 | t.start(); 84 | assertTrue(ai.compareAndSet(true, false)); 85 | t.join(0); 86 | assertFalse(t.isAlive()); 87 | 88 | } 89 | 90 | /* 91 | * getAndSet returns previous value and sets to given value 92 | */ 93 | public void testGetAndSet() { 94 | assertEquals(true,ai.getAndSet(false)); 95 | assertEquals(false,ai.getAndSet(false)); 96 | assertEquals(false,ai.getAndSet(true)); 97 | assertEquals(true,ai.get()); 98 | } 99 | /* 100 | * toString returns current value. 101 | */ 102 | public void testToString() { 103 | BooleanRecord ai = new BooleanRecord.Maker(db,"test2").make(); 104 | assertEquals(ai.toString(), Boolean.toString(false)); 105 | ai.set(true); 106 | assertEquals(ai.toString(), Boolean.toString(true)); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/record/StringRecordTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.record; 2 | 3 | import junit.framework.TestCase; 4 | import org.mapdb.db.DB; 5 | 6 | public class StringRecordTest extends TestCase { 7 | 8 | DB db; 9 | StringRecord ai; 10 | 11 | 12 | @Override 13 | protected void setUp() throws Exception { 14 | db = DB.Maker.memoryDB().make(); 15 | ai = new StringRecord.Maker(db, "test").init("test").make(); 16 | } 17 | 18 | @Override 19 | protected void tearDown() throws Exception { 20 | db.close(); 21 | } 22 | 23 | 24 | /* 25 | * constructor initializes to given value 26 | */ 27 | public void testConstructor() { 28 | assertEquals("test", ai.get()); 29 | } 30 | 31 | /* 32 | * default constructed initializes to empty string 33 | */ 34 | public void testConstructor2() { 35 | StringRecord ai = new StringRecord.Maker(db, "test2").make(); 36 | assertEquals("", ai.get()); 37 | } 38 | 39 | /* 40 | * get returns the last value set 41 | */ 42 | public void testGetSet() { 43 | assertEquals("test", ai.get()); 44 | ai.set("test2"); 45 | assertEquals("test2", ai.get()); 46 | ai.set("test3"); 47 | assertEquals("test3", ai.get()); 48 | 49 | } 50 | 51 | /* 52 | * compareAndSet succeeds in changing value if equal to expected else fails 53 | */ 54 | public void testCompareAndSet(){ 55 | assertTrue(ai.compareAndSet("test", "test2")); 56 | assertTrue(ai.compareAndSet("test2", "test3")); 57 | assertEquals("test3", ai.get()); 58 | assertFalse(ai.compareAndSet("test2", "test4")); 59 | assertNotSame("test5", ai.get()); 60 | assertTrue(ai.compareAndSet("test3", "test5")); 61 | assertEquals("test5", ai.get()); 62 | } 63 | 64 | /* 65 | * compareAndSet in one thread enables another waiting for value 66 | * to succeed 67 | */ 68 | public void testCompareAndSetInMultipleThreads() throws InterruptedException { 69 | Thread t = new Thread(new Runnable() { 70 | public void run() { 71 | while(!ai.compareAndSet("test2", "test3")) Thread.yield(); 72 | }}); 73 | 74 | t.start(); 75 | assertTrue(ai.compareAndSet("test", "test2")); 76 | t.join(0); 77 | assertFalse(t.isAlive()); 78 | assertEquals(ai.get(), "test3"); 79 | } 80 | 81 | /* 82 | * getAndSet returns previous value and sets to given value 83 | */ 84 | public void testGetAndSet(){ 85 | assertEquals("test", ai.getAndSet("test2")); 86 | assertEquals("test2", ai.getAndSet("test3")); 87 | assertEquals("test3", ai.getAndSet("test4")); 88 | } 89 | 90 | /* 91 | * toString returns current value. 92 | */ 93 | public void testToString() { 94 | assertEquals(ai.toString(), ai.get()); 95 | assertEquals(ai.toString(), "test"); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/record/VarRecordTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.record; 2 | 3 | import junit.framework.TestCase; 4 | import org.mapdb.db.DB; 5 | import org.mapdb.ser.Serializers; 6 | 7 | public class VarRecordTest extends TestCase { 8 | 9 | DB db; 10 | VarRecord ai; 11 | 12 | 13 | @Override 14 | protected void setUp() throws Exception { 15 | db = DB.Maker.memoryDB().make(); 16 | ai = new VarRecord.Maker(db, "test", Serializers.STRING).init("test").make(); 17 | } 18 | 19 | @Override 20 | protected void tearDown() throws Exception { 21 | db.close(); 22 | } 23 | 24 | 25 | /* 26 | * constructor initializes to given value 27 | */ 28 | public void testConstructor() { 29 | assertEquals("test", ai.get()); 30 | } 31 | 32 | /* 33 | * default constructed initializes to empty string 34 | */ 35 | public void testConstructor2() { 36 | try { 37 | VarRecord ai = new VarRecord.Maker(db, "test2", Serializers.STRING).make(); 38 | fail(); 39 | } catch (NullPointerException e){ 40 | } 41 | } 42 | 43 | public void testConstructor3() { 44 | VarRecord ai = new VarRecord.Maker(db, "test2", Serializers.STRING).init("aa").make(); 45 | assertEquals("aa", ai.get()); 46 | } 47 | 48 | 49 | /* 50 | * get returns the last value set 51 | */ 52 | public void testGetSet() { 53 | assertEquals("test", ai.get()); 54 | ai.set("test2"); 55 | assertEquals("test2", ai.get()); 56 | ai.set("test3"); 57 | assertEquals("test3", ai.get()); 58 | 59 | } 60 | 61 | /* 62 | * compareAndSet succeeds in changing value if equal to expected else fails 63 | */ 64 | public void testCompareAndSet(){ 65 | assertTrue(ai.compareAndSet("test", "test2")); 66 | assertTrue(ai.compareAndSet("test2", "test3")); 67 | assertEquals("test3", ai.get()); 68 | assertFalse(ai.compareAndSet("test2", "test4")); 69 | assertNotSame("test5", ai.get()); 70 | assertTrue(ai.compareAndSet("test3", "test5")); 71 | assertEquals("test5", ai.get()); 72 | } 73 | 74 | /* 75 | * compareAndSet in one thread enables another waiting for value 76 | * to succeed 77 | */ 78 | public void testCompareAndSetInMultipleThreads() throws InterruptedException { 79 | Thread t = new Thread(new Runnable() { 80 | public void run() { 81 | while(!ai.compareAndSet("test2", "test3")) Thread.yield(); 82 | }}); 83 | 84 | t.start(); 85 | assertTrue(ai.compareAndSet("test", "test2")); 86 | t.join(0); 87 | assertFalse(t.isAlive()); 88 | assertEquals(ai.get(), "test3"); 89 | } 90 | 91 | /* 92 | * getAndSet returns previous value and sets to given value 93 | */ 94 | public void testGetAndSet(){ 95 | assertEquals("test", ai.getAndSet("test2")); 96 | assertEquals("test2", ai.getAndSet("test3")); 97 | assertEquals("test3", ai.getAndSet("test4")); 98 | } 99 | 100 | /* 101 | * toString returns current value. 102 | */ 103 | public void testToString() { 104 | assertEquals(ai.toString(), ai.get()); 105 | assertEquals(ai.toString(), "test"); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/ser/SerializerArrayTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.IOException; 6 | import java.util.Arrays; 7 | 8 | import static org.junit.Assert.assertTrue; 9 | 10 | public class SerializerArrayTest { 11 | 12 | @Test 13 | public void subtype() throws IOException { 14 | String[] s = new String[]{"aa","bb"}; 15 | Serializer ser = new ArraySerializer(Serializers.STRING, String.class); 16 | 17 | String[] s2 = ser.clone(s); 18 | assertTrue(Arrays.equals(s,s2)); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/ser/SerializersJavaAccessTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser; 2 | 3 | import org.junit.Test; 4 | import org.mapdb.io.DataOutput2ByteArray; 5 | 6 | import java.io.IOException; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | import static org.junit.Assert.assertTrue; 10 | 11 | public class SerializersJavaAccessTest { 12 | 13 | @Test 14 | public void check_accessible() { 15 | assertTrue(Serializers.INTEGER instanceof Serializer); 16 | 17 | assertTrue(Serializers.BYTE_ARRAY instanceof Serializer); 18 | } 19 | 20 | @Test 21 | public void integer() throws IOException { 22 | DataOutput2ByteArray out = new DataOutput2ByteArray(); 23 | 24 | Integer i = new Integer(10); 25 | Serializers.INTEGER.serialize(out, i); 26 | assertEquals(out.pos, 4); 27 | } 28 | 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/ser/SerializersTest.kt: -------------------------------------------------------------------------------- 1 | package org.mapdb.ser 2 | 3 | import io.kotlintest.matchers.beGreaterThan 4 | import io.kotlintest.matchers.beLessThan 5 | import io.kotlintest.properties.forAll 6 | import io.kotlintest.should 7 | import org.mapdb.DBWordSpec 8 | import org.mapdb.TT 9 | 10 | class SerializersTest : DBWordSpec({ 11 | 12 | val sers = Serializers::class.java.fields 13 | .filter { it.name != "INSTANCE" } //TODO remove this field from java 14 | .map { Pair(it.name, it.get(null) as Serializer) } 15 | 16 | assert(sers.isNotEmpty()) 17 | 18 | 19 | for ((name, ser) in sers) { 20 | name should { 21 | val gen = TT.genFor(ser.serializedType()) 22 | "equals after clone "{ 23 | forAll(gen) { a -> 24 | val b = Serializers.clone(a, ser) 25 | ser.equals(a, b) 26 | } 27 | } 28 | "hash after clone"{ 29 | forAll(gen) { a -> 30 | val b = Serializers.clone(a, ser) 31 | ser.hashCode(a) == ser.hashCode(b!!) 32 | } 33 | } 34 | 35 | "equals not constant"{ 36 | forAll(gen, gen) { a, b -> 37 | Serializers.binaryEqual(ser, a, b) == ser.equals(a, b) 38 | } 39 | } 40 | 41 | 42 | "hash not constant"{ 43 | forAll(gen, gen) { a, b -> 44 | Serializers.binaryEqual(ser, a, b) == (ser.hashCode(a) == ser.hashCode(b)) 45 | } 46 | } 47 | 48 | 49 | if(!TT.shortTest()){ 50 | "hash variance and collisions"{ 51 | val slotsCount = 100_000 52 | val hashCount = 1e9.toLong() 53 | val variance = LongArray(slotsCount) 54 | val collisions = LongArray(slotsCount) 55 | val iter = gen.random().iterator() 56 | for(i in 0L until hashCount){ 57 | val r = iter.next() 58 | val hash = r.hashCode() 59 | 60 | // use div, to check its distributed from Integer.MIN_VALUE to Integer.MAX_VALUE 61 | variance[Math.abs(hash / slotsCount)]++ 62 | // use modulo to check for hash collisions 63 | collisions[Math.abs(hash % slotsCount)]++ 64 | 65 | } 66 | 67 | for(c in collisions){ 68 | c.toDouble() should beGreaterThan(0.1 * hashCount/slotsCount) 69 | } 70 | 71 | val lowVarCount = variance.filter{it< 0.0001 * hashCount/slotsCount }.size 72 | // 80% for almost empty hashes slots seems like too much, perhaps problem in random generator? 73 | lowVarCount.toDouble() should beLessThan(0.8 * slotsCount) 74 | 75 | } 76 | } 77 | } 78 | } 79 | 80 | }) 81 | 82 | fun serializersAll(): List> { 83 | return arrayListOf() 84 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/store/StoreReopenTest.kt: -------------------------------------------------------------------------------- 1 | package org.mapdb.store 2 | 3 | import io.kotlintest.shouldBe 4 | import org.junit.Assert.assertEquals 5 | import org.junit.Assert.assertTrue 6 | import org.junit.Test 7 | import org.mapdb.TT 8 | import org.mapdb.ser.Serializers 9 | import org.mapdb.store.legacy.Store2 10 | import org.mapdb.store.legacy.StoreDirect 11 | import org.mapdb.store.legacy.Volume 12 | import java.io.File 13 | import java.util.* 14 | 15 | 16 | class FileHeapBufStoreTest : StoreReopenTest() { 17 | override fun openStore(f:File) = FileHeapBufStore(f) 18 | } 19 | 20 | class FileHeapBufStoreRWLockTest : StoreReopenTest() { 21 | override fun openStore(f:File) = FileHeapBufStoreRWLock(f) 22 | } 23 | 24 | class LegacyStoreDirectTest : StoreReopenTest() { 25 | override fun openStore(f:File) = StoreDirect(Volume.fileFactory(f,1,false,0, Store2.VOLUME_CHUNK_SHIFT,1024)) 26 | } 27 | 28 | abstract class StoreReopenTest(): StoreTest(){ 29 | 30 | 31 | override fun openStore(): Store { 32 | val f = TT.tempFile() 33 | return openStore(f) 34 | } 35 | 36 | @Test fun reopen(){ 37 | TT.withTempFile { f-> 38 | var s = openStore(f) 39 | val recid = s.put("aa", Serializers.STRING) 40 | s.commit() 41 | s.close() 42 | 43 | s = openStore(f) 44 | s.get(recid,Serializers.STRING) shouldBe "aa" 45 | s.close() 46 | } 47 | } 48 | 49 | 50 | abstract fun openStore(file: File): Store 51 | // 52 | // abstract val headerType:Long 53 | 54 | // TODO file headers 55 | // 56 | // @Test open fun headerType(){ 57 | // val s = openStore(file) 58 | // s.put(11L, Serializers.LONG) 59 | // s.commit() 60 | // s.close() 61 | // val vol = RandomAccessFileVol.FACTORY.makeVolume(file.path, true) 62 | // assertEquals(CC.FILE_HEADER,vol.getUnsignedByte(0L).toLong()) 63 | // assertEquals(headerType, vol.getUnsignedByte(1L).toLong()) 64 | // } 65 | 66 | 67 | 68 | @Test fun put_reopen_get() { 69 | TT.withTempFile { file -> 70 | var e = openStore(file) 71 | val l = 11231203099090L 72 | val recid = e.put(l, Serializers.LONG) 73 | e.commit() 74 | e.close() 75 | e = openStore(file) 76 | 77 | assertEquals(l, e.get(recid, Serializers.LONG)) 78 | e.close() 79 | } 80 | } 81 | 82 | 83 | @Test fun put_reopen_get_large() { 84 | TT.withTempFile { file -> 85 | var e = openStore(file) 86 | 87 | val b = TT.randomByteArray(1000000) 88 | val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) 89 | e.commit() 90 | e.close() 91 | e = openStore(file) 92 | 93 | assertTrue(Arrays.equals(b, e.get(recid, Serializers.BYTE_ARRAY_NOSIZE))) 94 | e.verify() 95 | e.close() 96 | } 97 | } 98 | 99 | @Test fun large_record_update2() { 100 | TT.withTempFile { file -> 101 | var e = openStore(file) 102 | val b = TT.randomByteArray(1000000) 103 | val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) 104 | e.update(recid, Serializers.BYTE_ARRAY_NOSIZE, b) 105 | var b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) 106 | assertTrue(Arrays.equals(b, b2)) 107 | e.commit() 108 | e.close() 109 | e = openStore(file) 110 | 111 | b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) 112 | assertTrue(Arrays.equals(b, b2)) 113 | e.verify() 114 | e.close() 115 | } 116 | } 117 | 118 | @Test fun large_record_larger() { 119 | if(TT.shortTest()) 120 | return 121 | TT.withTempFile { file -> 122 | var e = openStore(file) 123 | val b = TT.randomByteArray(100000000) 124 | val recid = e.put(b, Serializers.BYTE_ARRAY_NOSIZE) 125 | var b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) 126 | assertTrue(Arrays.equals(b, b2)) 127 | e.verify() 128 | e.commit() 129 | e.close() 130 | e = openStore(file) 131 | 132 | b2 = e.get(recid, Serializers.BYTE_ARRAY_NOSIZE) 133 | assertTrue(Arrays.equals(b, b2)) 134 | e.verify() 135 | e.close() 136 | } 137 | } 138 | 139 | 140 | 141 | @Test fun test_store_reopen() { 142 | TT.withTempFile { file -> 143 | var e = openStore(file) 144 | val recid = e.put("aaa", Serializers.STRING) 145 | e.commit() 146 | e.commit() 147 | e.close() 148 | e = openStore(file) 149 | val aaa = e.get(recid, Serializers.STRING) 150 | assertEquals("aaa", aaa) 151 | e.verify() 152 | e.close() 153 | } 154 | } 155 | 156 | // TODO file locking 157 | // @Test fun file_lock(){ 158 | // TT.withTempFile { file -> 159 | // var e = openStore(file) 160 | // val recid = e.put("aaa", Serializers.STRING) 161 | // 162 | // assertFailsWith(DBException.FileLocked::class) { 163 | // openStore(file) 164 | // } 165 | // 166 | // e.close() 167 | // } 168 | // } 169 | // TODO missing test 170 | // @Test fun empty_rollback2(){ 171 | // val e = openStore(file) 172 | // if(e is StoreTx) 173 | // e.rollback() 174 | // e.close() 175 | // } 176 | 177 | @Test fun empty_commit2(){ 178 | TT.withTempFile { file -> 179 | val e = openStore(file) 180 | e.commit() 181 | e.close() 182 | } 183 | } 184 | 185 | 186 | 187 | } --------------------------------------------------------------------------------