├── .gitignore ├── .travis.yml ├── src ├── test │ └── java │ │ ├── org │ │ └── mapdb │ │ │ ├── CCTest.java │ │ │ ├── Issue114Test.java │ │ │ ├── StoreHeapTest.java │ │ │ ├── StoreHeapTxTest.java │ │ │ ├── IssuesTest.java │ │ │ ├── Issue321Test.java │ │ │ ├── Issue198Test.java │ │ │ ├── BTreeSetTest.java │ │ │ ├── Issue170Test.java │ │ │ ├── Issue112Test.java │ │ │ ├── Issue78Test.java │ │ │ ├── BTreeMapNavigableSubMapInclusiveTest.java │ │ │ ├── Issue247Test.java │ │ │ ├── Issue90Test.java │ │ │ ├── Issue381Test.java │ │ │ ├── Issue312Test.java │ │ │ ├── BTreeMapNavigableSubMapExclusiveTest.java │ │ │ ├── StoreCacheHashTableTest.java │ │ │ ├── Issue440Test.java │ │ │ ├── DataOutput2Test.java │ │ │ ├── Issue258Test.java │ │ │ ├── Issue265Test.java │ │ │ ├── Issue308Test.java │ │ │ ├── Issue237Test.java │ │ │ ├── Issue157Test.java │ │ │ ├── Exec.java │ │ │ ├── Pump_InMemory_Import_Then_Save_To_Disk.java │ │ │ ├── BTreeMapParTest.java │ │ │ ├── JSR166TestCase.java │ │ │ ├── CacheWeakSoftRefTest.java │ │ │ ├── StoreTest.java │ │ │ ├── Issue37Test.java │ │ │ ├── Issue69Test.java │ │ │ ├── Issue418Test.java │ │ │ ├── Issue86Test.java │ │ │ ├── Issue183Test.java │ │ │ ├── Issue77Test.java │ │ │ ├── StoreLongLongMapTest.java │ │ │ ├── StoreLongObjectMapTest.java │ │ │ ├── Issue419Test.java │ │ │ ├── BTreeMapContainsKeyTest.java │ │ │ ├── Issue266Test.java │ │ │ ├── Issue89Test.java │ │ │ ├── CompressTest.java │ │ │ ├── ExamplesTest.java │ │ │ ├── FunTest.java │ │ │ ├── Issue241.java │ │ │ ├── Serialized2DerivedBean.java │ │ │ ├── MapListenerTest.java │ │ │ ├── Issue132Test.java │ │ │ ├── Issue353Test.java │ │ │ ├── BTreeMapTest2.java │ │ │ ├── Issue400Test.java │ │ │ ├── Issue249Test.java │ │ │ ├── BTreeMapLargeValsTest.java │ │ │ ├── HTreeMap3Test.java │ │ │ ├── StoreCachedTest.java │ │ │ ├── Serialization2Bean.java │ │ │ ├── Issue154Test.java │ │ │ ├── SerializerTest.java │ │ │ ├── Serialization2Test.java │ │ │ ├── AtomicBooleanTest.java │ │ │ ├── Issue164Test.java │ │ │ ├── Issue150Test.java │ │ │ ├── Issue162Test.java │ │ │ ├── PumpComparableValueTest.java │ │ │ ├── StoreAppendTest.java │ │ │ ├── TxEngineTest.java │ │ │ ├── StoreDirectFreeSpaceTest.java │ │ │ ├── Issue332Test.java │ │ │ ├── TestTransactions.java │ │ │ ├── ClosedThrowsExceptionTest.java │ │ │ ├── QueuesTest.java │ │ │ ├── AsyncWriteEngineTest.java │ │ │ └── DataIOTest.java │ │ └── examples │ │ ├── Transactions2.java │ │ ├── _TempMap.java │ │ ├── Secondary_Map.java │ │ ├── Bidi_Map.java │ │ ├── _HelloWorld.java │ │ ├── Map_Size_Counter.java │ │ ├── SQL_Auto_Incremental_Unique_Key.java │ │ ├── Secondary_Key.java │ │ ├── Histogram.java │ │ ├── MultiMap.java │ │ ├── CacheOffHeap.java │ │ ├── Compression.java │ │ ├── CacheEntryExpiry.java │ │ ├── Secondary_Values.java │ │ ├── CacheOffHeapAdvanced.java │ │ ├── Lazily_Loaded_Records.java │ │ ├── Transactions.java │ │ ├── TreeMap_Performance_Tunning.java │ │ ├── Huge_Insert.java │ │ └── Custom_Value.java └── main │ └── java │ └── org │ └── mapdb │ ├── TxBlock.java │ ├── TxRollbackException.java │ ├── DBException.java │ ├── TxMaker.java │ └── CC.java ├── README.md ├── notice.txt └── logger.properties /.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 -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | cache: 3 | directories: 4 | - $HOME/.m2 5 | 6 | jdk: 7 | - oraclejdk8 8 | - oraclejdk7 9 | - openjdk7 10 | - openjdk6 11 | 12 | install: true 13 | 14 | script: mvn test 15 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/CCTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | public class CCTest { 9 | 10 | @Test public void concurency(){ 11 | assertEquals(CC.DEFAULT_LOCK_SCALE, DataIO.nextPowTwo(CC.DEFAULT_LOCK_SCALE)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue114Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | public class Issue114Test { 7 | 8 | @Test 9 | public void test(){ 10 | DB db = DBMaker.tempFileDB() 11 | //.randomAccessFileEnable() 12 | .transactionDisable().make(); 13 | db.getCircularQueue("test"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/StoreHeapTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | public class StoreHeapTest extends EngineTest{ 5 | 6 | 7 | @Override 8 | protected StoreHeap openEngine() { 9 | return new StoreHeap(true,CC.DEFAULT_LOCK_SCALE,0); 10 | } 11 | 12 | @Override boolean canReopen(){return false;} 13 | 14 | @Override boolean canRollback(){return false;} 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/StoreHeapTxTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | public class StoreHeapTxTest extends EngineTest{ 5 | 6 | 7 | @Override 8 | protected StoreHeap openEngine() { 9 | return new StoreHeap(false,CC.DEFAULT_LOCK_SCALE,0); 10 | } 11 | 12 | @Override boolean canReopen(){return false;} 13 | 14 | @Override boolean canRollback(){return true;} 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/IssuesTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Map; 6 | 7 | public class IssuesTest { 8 | 9 | @Test public void issue130(){ 10 | DB db = DBMaker.appendFileDB(UtilsTest.tempDbFile()) 11 | .closeOnJvmShutdown() 12 | .make(); 13 | 14 | Map store = db.treeMap("collectionName"); 15 | 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue321Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class Issue321Test { 10 | 11 | @Test 12 | public void npe(){ 13 | 14 | DB db = DBMaker.memoryDB().make(); 15 | 16 | List l = Arrays.asList(19,10,9,8,2); 17 | 18 | Map m = db.treeMapCreate("aa") 19 | .pumpPresort(100) 20 | .make(); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue198Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | 7 | public class Issue198Test { 8 | 9 | @Test public void main() { 10 | 11 | DB db = DBMaker.fileDB(UtilsTest.tempDbFile()) 12 | .closeOnJvmShutdown() 13 | //.randomAccessFileEnable() 14 | .make(); 15 | BTreeMap map = db.treeMapCreate("testmap").makeOrGet(); 16 | for(int i = 1; i <= 3000; ++i) 17 | map.put(i, i); 18 | db.commit(); 19 | db.close(); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/BTreeSetTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Before; 5 | 6 | import java.util.Collections; 7 | 8 | @SuppressWarnings({ "unchecked", "rawtypes" }) 9 | public class BTreeSetTest extends HTreeSetTest{ 10 | 11 | @Before 12 | public void setUp() throws Exception { 13 | 14 | hs = new BTreeMap(engine,false, 15 | BTreeMap.createRootRef(engine,BTreeKeySerializer.BASIC,null,0), 16 | 6,false,0, BTreeKeySerializer.BASIC,null, 17 | 0).keySet(); 18 | 19 | Collections.addAll(hs, objArray); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue170Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Map; 6 | import java.util.UUID; 7 | 8 | @SuppressWarnings({"rawtypes","unchecked"}) 9 | public class Issue170Test { 10 | 11 | @Test 12 | public void test(){ 13 | Map m = DBMaker.memoryDB() 14 | .compressionEnable() 15 | .transactionDisable() 16 | .make().treeMapCreate("test").make(); 17 | for(int i=0;i<1e5;i++){ 18 | m.put(UUID.randomUUID().toString(),UUID.randomUUID().toString()); 19 | } 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MapDB provides concurrent Maps, Sets and Queues backed by disk storage or off-heap memory. 2 | MapDB is free as speech and free as beer under 3 | [Apache License 2.0](https://github.com/jankotek/MapDB/blob/master/doc/license.txt). 4 | 5 | Find out more at: 6 | * [Home page - www.mapdb.org](http://www.mapdb.org) 7 | * [Introduction](http://www.mapdb.org/doc/getting-started.html) 8 | * [Examples](https://github.com/jankotek/MapDB/tree/master/src/test/java/examples) 9 | * [Javadoc](http://www.mapdb.org/apidocs/index.html) 10 | 11 | 12 | 15 minutes overview 13 | ------------ 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue112Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | public class Issue112Test { 9 | 10 | 11 | @Test(timeout=10000) 12 | public void testDoubleCommit() throws Exception { 13 | final DB myTestDataFile = DBMaker.fileDB(UtilsTest.tempDbFile()) 14 | .checksumEnable() 15 | .make(); 16 | myTestDataFile.commit(); 17 | myTestDataFile.commit(); 18 | 19 | long recid = myTestDataFile.engine.put("aa",Serializer.STRING_NOSIZE); 20 | myTestDataFile.commit(); 21 | 22 | assertEquals("aa",myTestDataFile.engine.get(recid, Serializer.STRING_NOSIZE)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue78Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.IOError; 8 | 9 | /* 10 | * https://github.com/jankotek/MapDB/issues/78 11 | * 12 | * @author Nandor Kracser 13 | */ 14 | public class Issue78Test { 15 | 16 | @Before 17 | public void setUp() { 18 | } 19 | 20 | @After 21 | public void tearDown() { 22 | } 23 | 24 | @Test(expected = IOError.class, timeout = 10000) 25 | public void testIssue() { 26 | DB db = DBMaker.tempFileDB().make(); 27 | HTreeMap usersMap = db.hashMap("values"); 28 | usersMap.put("thisKillsTheAsyncWriteThread", new NotSerializable()); 29 | db.commit(); 30 | } 31 | 32 | class NotSerializable { 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/BTreeMapNavigableSubMapInclusiveTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import java.util.NavigableMap; 4 | 5 | public class BTreeMapNavigableSubMapInclusiveTest extends BTreeMapNavigable2Test{ 6 | 7 | public static class Outside extends BTreeMapNavigableSubMapInclusiveTest{ 8 | @Override protected NavigableMap newMap() { 9 | return DBMaker.memoryDB().transactionDisable().make().treeMapCreate("map").valuesOutsideNodesEnable().make(); 10 | } 11 | } 12 | 13 | 14 | @Override 15 | public void setUp() throws Exception { 16 | super.setUp(); 17 | map.put(0,"zero"); 18 | map.put(11,"eleven"); 19 | map = map.subMap(1,true,10,true); 20 | } 21 | 22 | 23 | @Override 24 | public void testPut(){ 25 | //this test is not run on submaps 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/TxBlock.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; 18 | 19 | /** 20 | * Wraps single transaction in a block 21 | */ 22 | public interface TxBlock { 23 | 24 | void tx(DB db) throws TxRollbackException; 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue247Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.util.Map; 8 | 9 | public class Issue247Test { 10 | 11 | private Map getMap(DB db){ 12 | return db.treeMapCreate("test") 13 | .counterEnable() 14 | .valuesOutsideNodesEnable() 15 | .makeOrGet(); 16 | } 17 | 18 | 19 | @Test 20 | public void test(){ 21 | File f = UtilsTest.tempDbFile(); 22 | DB db = DBMaker.fileDB(f) 23 | .transactionDisable() 24 | .make(); 25 | 26 | getMap(db); 27 | //db.commit(); 28 | 29 | db.close(); 30 | 31 | db = DBMaker.fileDB(f) 32 | .readOnly() 33 | .make(); 34 | getMap(db).size(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue90Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.File; 6 | 7 | public class Issue90Test { 8 | 9 | @Test 10 | public void testCounter() throws Exception { 11 | File file = UtilsTest.tempDbFile(); 12 | 13 | 14 | final DB mapDb =DBMaker.appendFileDB(file) 15 | .closeOnJvmShutdown() 16 | .compressionEnable() //This is the cause of the exception. If compression is not used, no exception occurs. 17 | .make(); 18 | final Atomic.Long myCounter = mapDb.atomicLong("MyCounter"); 19 | 20 | final BTreeMap> treeMap = mapDb.treeMap("map"); 21 | Bind.size(treeMap, myCounter); 22 | 23 | for (int i = 0; i < 3; i++) { 24 | treeMap.put("key_" + i, new Fun.Pair("value_", i)); 25 | } 26 | } 27 | 28 | 29 | 30 | } -------------------------------------------------------------------------------- /src/test/java/examples/Transactions2.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.*; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * Demonstrates easier way to execute concurrent transactions. 9 | */ 10 | public class Transactions2 { 11 | 12 | public static void main(String[] args) { 13 | TxMaker txMaker = DBMaker.memoryDB().makeTxMaker(); 14 | 15 | // Execute transaction within single block. 16 | txMaker.execute(new TxBlock(){ 17 | @Override public void tx(DB db) throws TxRollbackException { 18 | Map m = db.hashMap("test"); 19 | m.put("test","test"); 20 | } 21 | }); 22 | 23 | //show result of block execution 24 | DB tx1 = txMaker.makeTx(); 25 | Object val = tx1.hashMap("test").get("test"); 26 | System.out.println(val); 27 | 28 | tx1.close(); 29 | txMaker.close(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue381Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.File; 6 | import java.util.concurrent.ConcurrentMap; 7 | 8 | public class Issue381Test { 9 | 10 | 11 | @Test 12 | public void testCorruption() 13 | throws Exception 14 | { 15 | 16 | File f = UtilsTest.tempDbFile(); 17 | 18 | for(int j=0;j<10;j++) { 19 | final int INSTANCES = 1000; 20 | TxMaker txMaker = DBMaker.fileDB(f).makeTxMaker(); 21 | 22 | DB tx = txMaker.makeTx(); 23 | byte[] data = new byte[128]; 24 | 25 | ConcurrentMap map = tx.hashMap("persons"); 26 | map.clear(); 27 | for (int i = 0; i < INSTANCES; i++) { 28 | map.put((long) i, data); 29 | } 30 | tx.commit(); 31 | txMaker.close(); 32 | } 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/examples/_TempMap.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.BTreeMap; 4 | import org.mapdb.DBMaker; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * Opens maps backed by file in temporary folder. 10 | * Quick and simple way to get Maps which can handle billions of items. 11 | * All files are deleted after Map is closed or JVM exits (using shutdown hook). 12 | */ 13 | public class _TempMap { 14 | public static void main(String[] args) { 15 | 16 | // open new empty map 17 | // DBMaker will create files in temporary folder and opens it 18 | Map map = DBMaker.tempTreeMap(); 19 | 20 | //put some stuff into map 21 | //all data are stored in file in temp folder 22 | map.put("aa", "bb"); 23 | map.put("cc", "dd"); 24 | 25 | // After JVM exits files are deleted. 26 | // This map was temporary, there is no way to recover its data ! 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue312Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.File; 6 | import java.io.IOException; 7 | import java.util.Map; 8 | 9 | public class Issue312Test { 10 | 11 | @Test 12 | public void test() throws IOException{ 13 | File f = File.createTempFile("mapdb","test"); 14 | DB db = DBMaker.fileDB(f) 15 | .mmapFileEnableIfSupported() 16 | .transactionDisable() 17 | .make(); 18 | 19 | Map map = db.treeMapCreate("data").make(); 20 | for(long i = 0; i<100000;i++){ 21 | map.put(i,i + "hi my friend " + i); 22 | } 23 | db.commit(); 24 | db.close(); 25 | 26 | db = DBMaker.fileDB(f) 27 | .mmapFileEnableIfSupported() 28 | .transactionDisable() 29 | .readOnly() 30 | .make(); 31 | 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/BTreeMapNavigableSubMapExclusiveTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import java.util.NavigableMap; 4 | 5 | public class BTreeMapNavigableSubMapExclusiveTest extends BTreeMapNavigable2Test{ 6 | 7 | public static class Outside extends BTreeMapNavigableSubMapExclusiveTest{ 8 | @Override protected NavigableMap newMap() { 9 | return DBMaker.memoryDB().transactionDisable().make().treeMapCreate("map").valuesOutsideNodesEnable() 10 | .make(); 11 | } 12 | 13 | } 14 | 15 | @Override 16 | public void setUp() throws Exception { 17 | super.setUp(); 18 | map.put(-1,"-one"); 19 | map.put(0,"zero"); 20 | map.put(11,"eleven"); 21 | map.put(12,"twelve"); 22 | map = map.subMap(0,false,11,false); 23 | } 24 | 25 | 26 | @Override 27 | public void testPut(){ 28 | //this test is not run on submaps 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/StoreCacheHashTableTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import java.io.File; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class StoreCacheHashTableTest extends EngineTest{ 8 | 9 | File f = UtilsTest.tempDbFile(); 10 | 11 | @Override protected E openEngine() { 12 | StoreDirect e =new StoreDirect( 13 | f.getPath(), 14 | Volume.fileFactory(), 15 | new Store.Cache.HashTable(1024,false), 16 | CC.DEFAULT_LOCK_SCALE, 17 | 0, 18 | false, 19 | false, 20 | null, 21 | false, 22 | 0, 23 | false, 24 | 0, 25 | null 26 | ); 27 | e.init(); 28 | return (E)e; 29 | } 30 | 31 | @Override 32 | boolean canRollback() { 33 | return false; 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/org/mapdb/TxRollbackException.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; 18 | 19 | /** 20 | * Exception thrown when transaction is rolled back. 21 | * @author Jan Kotek 22 | */ 23 | public class TxRollbackException extends RuntimeException { 24 | 25 | private static final long serialVersionUID = -708303624605410767L; 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue440Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.NavigableSet; 6 | 7 | public class Issue440Test { 8 | 9 | @Test 10 | public void first(){ 11 | DB db = DBMaker.memoryDB().make(); 12 | 13 | NavigableSet set1 = db.treeSetCreate("set1") 14 | .serializer(BTreeKeySerializer.ARRAY2) 15 | .makeOrGet(); 16 | 17 | db = DBMaker.memoryDB().transactionDisable().make(); 18 | 19 | NavigableSet set2 = db.treeSetCreate("set2") 20 | .serializer(BTreeKeySerializer.ARRAY2) 21 | .makeOrGet(); 22 | } 23 | 24 | @Test public void second(){ 25 | DB db = DBMaker.tempFileDB().make(); 26 | 27 | NavigableSet set1 = db.treeSetCreate("set1") 28 | .serializer(BTreeKeySerializer.ARRAY2) 29 | .makeOrGet(); 30 | 31 | db.commit(); 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/DataOutput2Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | 8 | public class DataOutput2Test { 9 | 10 | //TODO more tests here for compability between DataIO.ByteArrayDataOutput and other DataInputs 11 | 12 | DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); 13 | 14 | DataIO.DataInputByteArray in(){ 15 | return new DataIO.DataInputByteArray(out.buf); 16 | } 17 | 18 | @Test 19 | public void testWriteFloat() throws Exception { 20 | float f = 12.1239012093e-19F; 21 | out.writeFloat(f); 22 | DataIO.DataInputByteArray in = in(); 23 | assertEquals(Float.floatToIntBits(f),Float.floatToIntBits(in.readFloat())); 24 | assertEquals(4,in.pos); 25 | } 26 | 27 | @Test 28 | public void testWriteDouble() throws Exception { 29 | double f = 12.123933423523012093e-199; 30 | out.writeDouble(f); 31 | DataIO.DataInputByteArray in = in(); 32 | assertEquals(Double.doubleToLongBits(f),Double.doubleToLongBits(in.readDouble())); 33 | assertEquals(8,in.pos); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue258Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.concurrent.BlockingQueue; 9 | 10 | public class Issue258Test { 11 | 12 | 13 | @Test 14 | public void test() throws IOException { 15 | 16 | File tmp = File.createTempFile("mapdb",""); 17 | 18 | 19 | for(int i=0;i<10;i++){ 20 | DB db = DBMaker.fileDB(tmp) 21 | .mmapFileEnable() 22 | // .closeOnJvmShutdown() 23 | // .compressionEnable() 24 | // .cacheLRUEnable() 25 | // .asyncWriteEnable() 26 | .make(); 27 | 28 | BlockingQueue map = db.getStack("undolog"); 29 | 30 | for(int j=0; !map.isEmpty() && j < 100; j++) 31 | { 32 | Object obj = map.poll(); 33 | 34 | } 35 | map.clear(); 36 | 37 | for (int k=0; k < 100000; k++) 38 | { 39 | 40 | String cmd = "iasdkaokdas"+i; 41 | map.add(cmd); 42 | } 43 | 44 | db.commit(); 45 | db.close(); 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue265Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.util.Map; 7 | 8 | public class Issue265Test { 9 | 10 | @Test 11 | public void compact(){ 12 | DB db = DBMaker.memoryDB() 13 | .transactionDisable() 14 | .make(); // breaks functionality even in version 0.9.7 15 | 16 | Map map = db.hashMap("HashMap"); 17 | map.put(1, "one"); 18 | map.put(2, "two"); 19 | map.remove(1); 20 | db.commit(); 21 | db.compact(); 22 | Assert.assertEquals(1, map.size()); 23 | 24 | db.close(); 25 | 26 | } 27 | 28 | @Test 29 | public void compact_no_tx(){ 30 | DB db = DBMaker.memoryDB().make(); 31 | 32 | Map map = db.hashMap("HashMap"); 33 | map.put(1, "one"); 34 | map.put(2, "two"); 35 | map.remove(1); 36 | db.commit(); 37 | db.compact(); 38 | Assert.assertEquals(1, map.size()); 39 | 40 | db.close(); 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/examples/Secondary_Map.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.Bind; 4 | import org.mapdb.DBMaker; 5 | import org.mapdb.Fun; 6 | import org.mapdb.HTreeMap; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * Shows how to create secondary map 13 | * which is synchronized with primary map 14 | */ 15 | public class Secondary_Map { 16 | 17 | public static void main(String[] args) { 18 | HTreeMap primary = DBMaker.memoryDB().make().hashMap("test"); 19 | 20 | // secondary map will hold String.size() from primary map as its value 21 | Map secondary = new HashMap(); //can be normal java map, or MapDB map 22 | 23 | 24 | //Bind maps together. It is one way binding, so changes in primary are reflected in secondary 25 | Bind.secondaryValue(primary, secondary, new Fun.Function2() { 26 | @Override public Integer run(Long key, String value) { 27 | return value.length(); 28 | } 29 | }); 30 | 31 | 32 | primary.put(111L, "just some chars"); 33 | int strSize = secondary.get(111L); 34 | System.out.println(strSize); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/examples/Bidi_Map.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.Bind; 4 | import org.mapdb.DBMaker; 5 | import org.mapdb.Fun; 6 | import org.mapdb.HTreeMap; 7 | 8 | import java.util.NavigableSet; 9 | import java.util.TreeSet; 10 | 11 | /** 12 | * Simple way to create bidirectional map (can find key for given value) using Binding. 13 | */ 14 | public class Bidi_Map { 15 | 16 | public static void main(String[] args) { 17 | //primary map 18 | HTreeMap map = DBMaker.tempHashMap(); 19 | 20 | // inverse mapping for primary map 21 | NavigableSet inverseMapping = new TreeSet(Fun.COMPARABLE_ARRAY_COMPARATOR); 22 | //NOTE: you may also use Set provided by MapDB to make it persistent 23 | 24 | // bind inverse mapping to primary map, so it is auto-updated 25 | Bind.mapInverse(map, inverseMapping); 26 | 27 | 28 | map.put(10L,"value2"); 29 | map.put(1111L,"value"); 30 | map.put(1112L,"value"); 31 | map.put(11L,"val"); 32 | 33 | //now find all keys for given value 34 | for(Object[] key: Fun.filter(inverseMapping, "value")){ 35 | System.out.println("Key for 'value' is: "+key[1]); 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue308Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Iterator; 6 | import java.util.concurrent.atomic.AtomicLong; 7 | 8 | public class Issue308Test { 9 | 10 | @Test 11 | public void test() { 12 | DB db = DBMaker.tempFileDB() 13 | .mmapFileEnableIfSupported() 14 | .compressionEnable() 15 | .transactionDisable() 16 | .checksumEnable() 17 | .commitFileSyncDisable() 18 | .make(); 19 | Iterator> newIterator = new Iterator>() { 20 | private AtomicLong value = new AtomicLong(10000000); 21 | 22 | @Override 23 | public boolean hasNext() { 24 | return value.get() > 0; 25 | } 26 | 27 | @Override 28 | public Fun.Pair next() { 29 | Long v = value.decrementAndGet(); 30 | return new Fun.Pair(v, v.toString()); 31 | } 32 | 33 | @Override 34 | public void remove() { 35 | 36 | } 37 | }; 38 | BTreeMap cubeData = db.treeMapCreate("data").pumpSource(newIterator).make(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue237Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.File; 6 | import java.util.concurrent.BlockingQueue; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | 11 | public class Issue237Test { 12 | 13 | File file = UtilsTest.tempDbFile(); 14 | 15 | 16 | @Test 17 | public void testReopenAsync() throws InterruptedException { 18 | DB database = DBMaker.fileDB( file ).asyncWriteEnable().make(); 19 | testQueue( database ); 20 | 21 | database = DBMaker.fileDB( file ).asyncWriteEnable().make(); 22 | testQueue( database ); 23 | } 24 | 25 | @Test 26 | public void testReopenSync() throws InterruptedException { 27 | file.delete(); 28 | 29 | DB database = DBMaker.fileDB( file ).make(); 30 | testQueue( database ); 31 | 32 | database = DBMaker.fileDB( file ).make(); 33 | testQueue( database ); 34 | } 35 | 36 | private void testQueue( DB database ) throws InterruptedException { 37 | BlockingQueue queue = database.getQueue( "test-queue" ); 38 | queue.add( "test-value" ); 39 | database.commit(); 40 | assertEquals(queue.take(), "test-value"); 41 | database.commit(); 42 | database.close(); 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue157Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Map; 6 | 7 | import static org.junit.Assert.assertTrue; 8 | 9 | public class Issue157Test { 10 | 11 | @Test 12 | public void concurrent_BTreeMap() throws InterruptedException { 13 | DB db = DBMaker.memoryDB().make(); 14 | final BTreeMap map = db.treeMap("COL_2"); 15 | map.clear(); 16 | 17 | Thread t1 = new Thread() { 18 | public void run() { 19 | for(int i=0; i<=10000; i++) { 20 | map.put(i, "foo"); 21 | } 22 | } 23 | }; 24 | 25 | Thread t2 = new Thread() { 26 | public void run() { 27 | for(int i=10000; i>=0; i--) { 28 | map.put(i, "bar"); 29 | } 30 | } 31 | }; 32 | 33 | t1.start(); 34 | t2.start(); 35 | 36 | t1.join(); 37 | t2.join(); 38 | 39 | // map.printTreeStructure(); 40 | 41 | for(Map.Entry entry : map.entrySet()) { 42 | // System.out.println(entry.getKey() + " => " + entry.getValue()); 43 | assertTrue(""+entry.getKey(),"bar".equals(entry.getValue())||"foo".equals(entry.getValue())); 44 | } 45 | 46 | 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Exec.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.concurrent.*; 6 | 7 | /* 8 | * 9 | */ 10 | public class Exec { 11 | 12 | public static void execNTimes(int n, final Callable r){ 13 | ExecutorService s = Executors.newFixedThreadPool(n); 14 | final CountDownLatch wait = new CountDownLatch(n); 15 | 16 | List f = new ArrayList(); 17 | 18 | Runnable r2 = new Runnable(){ 19 | 20 | @Override 21 | public void run() { 22 | wait.countDown(); 23 | try { 24 | wait.await(); 25 | } catch (InterruptedException e) { 26 | throw new RuntimeException(e); 27 | } 28 | try { 29 | r.call(); 30 | } catch (Exception e) { 31 | throw new RuntimeException(e); 32 | } 33 | } 34 | }; 35 | 36 | for(int i=0;i map = db.treeMap("collectionName"); 28 | 29 | map.put(1,"one"); 30 | map.put(2,"two"); 31 | //map.keySet() is now [1,2] even before commit 32 | 33 | db.commit(); //persist changes into disk 34 | 35 | map.put(3,"three"); 36 | //map.keySet() is now [1,2,3] 37 | db.rollback(); //revert recent changes 38 | //map.keySet() is now [1,2] 39 | 40 | db.close(); 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Pump_InMemory_Import_Then_Save_To_Disk.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import java.io.File; 4 | import java.util.Map; 5 | import java.util.Random; 6 | 7 | /* 8 | * This demonstrates using Data Pump to first create store in-memory at maximal speed, 9 | * and than copy the store into memory 10 | */ 11 | //TODO Pump between stores is disabled for now, copy this back to examples once enabled 12 | public class Pump_InMemory_Import_Then_Save_To_Disk { 13 | 14 | public static void main(String[] args) { 15 | // if(1==1) return; 16 | // 17 | // //create inMemory store which does not use serialization, 18 | // //and has speed comparable to `java.util` collections 19 | // DB inMemory = new DB(new StoreHeap(transactionsDisabled)); 20 | // Map m = inMemory.getTreeMap("test"); 21 | // 22 | // Random r = new Random(); 23 | // //insert random stuff, keep on mind it needs to fit into memory 24 | // for(int i=0;i<10000;i++){ 25 | // m.put(r.nextInt(),"dwqas"+i); 26 | // } 27 | // 28 | // //now create on-disk store, it needs to be completely empty 29 | // File targetFile = UtilsTest.tempDbFile(); 30 | // DB target = DBMaker.fileDB(targetFile).make(); 31 | // 32 | // Pump.copy(inMemory, target); 33 | // 34 | // inMemory.close(); 35 | // target.close(); 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/BTreeMapParTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.concurrent.*; 6 | import java.util.concurrent.atomic.AtomicLong; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class BTreeMapParTest { 11 | 12 | 13 | final int threadNum = 6; 14 | final int max = (int) 1e6; 15 | 16 | @Test 17 | public void parInsert() throws InterruptedException { 18 | 19 | 20 | final ConcurrentMap m = DBMaker.memoryDB().transactionDisable().make() 21 | .treeMapCreate("test") 22 | .valueSerializer(Serializer.LONG) 23 | .keySerializer(BTreeKeySerializer.LONG) 24 | .makeLongMap(); 25 | 26 | long t = System.currentTimeMillis(); 27 | final AtomicLong counter = new AtomicLong(); 28 | 29 | Exec.execNTimes(threadNum, new Callable() { 30 | @Override 31 | public Object call() throws Exception { 32 | long core = counter.getAndIncrement(); 33 | for (Long n = core; n < max; n += threadNum) { 34 | m.put(n, n); 35 | } 36 | 37 | return null; 38 | } 39 | }); 40 | 41 | // System.out.printf(" Threads %d, time %,d\n",threadNum,System.currentTimeMillis()-t); 42 | 43 | 44 | assertEquals(max,m.size()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/examples/Map_Size_Counter.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.*; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * Keep tracks of number of items in map. 9 | *

10 | * {@code Collections.size()} typically requires traversing entire collection in MapDB, but there is optional parameter 11 | * which controls if Map keeps track of its count. 12 | */ 13 | public class Map_Size_Counter { 14 | 15 | public static void main(String[] args) { 16 | 17 | //first option, create Map with counter (NOTE: counter is not on by default) 18 | DB db1 = DBMaker.tempFileDB().make(); 19 | //hashMap 20 | Map m = db1.hashMapCreate("map1a") 21 | .counterEnable() /**< map = db.treeMap("map"); 21 | 22 | // open existing or create new Atomic record with given name 23 | // if no record with given name exist, new recid is created with value `0` 24 | Atomic.Long keyinc = db.atomicLong("map_keyinc"); 25 | 26 | 27 | // Allocate new unique key to use in map 28 | // Atomic.Long will use `compare-and-swap` operation to atomically store incremented value 29 | // Key values can be used only for single insert 30 | // key == 1 31 | Long key = keyinc.incrementAndGet(); 32 | map.put(key, "some string"); 33 | 34 | // insert second entry, 35 | // key==2 36 | map.put(keyinc.incrementAndGet(), "some other string"); 37 | 38 | System.out.println(map); 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/examples/Secondary_Key.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.BTreeMap; 4 | import org.mapdb.Bind; 5 | import org.mapdb.DBMaker; 6 | import org.mapdb.Fun; 7 | 8 | import java.util.NavigableSet; 9 | import java.util.TreeSet; 10 | 11 | /** 12 | * Shows howto use secondary non-unique keys, 13 | */ 14 | public class Secondary_Key { 15 | 16 | public static void main(String[] args) { 17 | 18 | // stores string under id 19 | BTreeMap primary = DBMaker.tempTreeMap(); 20 | 21 | 22 | // stores value hash from primary map 23 | NavigableSet valueHash = 24 | new TreeSet(Fun.COMPARABLE_ARRAY_COMPARATOR); //any Set will do 25 | 26 | // bind secondary to primary so it contains secondary key 27 | Bind.secondaryKey(primary, valueHash, new Fun.Function2() { 28 | @Override 29 | public Integer run(Long key, String value) { 30 | return value.hashCode(); 31 | } 32 | }); 33 | 34 | 35 | //insert some stuff into primary 36 | primary.put(111L, "some value"); 37 | primary.put(112L, "some value"); 38 | 39 | //shot content of secondary 40 | System.out.println(valueHash); 41 | 42 | //get all keys where value hashCode is N 43 | Iterable ids = Fun.filter(valueHash, 1571230533); 44 | System.out.println(ids.iterator().next()[1]); 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/JSR166TestCase.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import junit.framework.TestCase; 4 | 5 | abstract public class JSR166TestCase extends TestCase { 6 | 7 | /* 8 | * The number of elements to place in collections, arrays, etc. 9 | */ 10 | public static final int SIZE = 20; 11 | 12 | 13 | 14 | public static final Integer zero = new Integer(0); 15 | public static final Integer one = new Integer(1); 16 | public static final Integer two = new Integer(2); 17 | public static final Integer three = new Integer(3); 18 | public static final Integer four = new Integer(4); 19 | public static final Integer five = new Integer(5); 20 | public static final Integer six = new Integer(6); 21 | public static final Integer seven = new Integer(7); 22 | public static final Integer eight = new Integer(8); 23 | public static final Integer nine = new Integer(9); 24 | public static final Integer m1 = new Integer(-1); 25 | public static final Integer m2 = new Integer(-2); 26 | public static final Integer m3 = new Integer(-3); 27 | public static final Integer m4 = new Integer(-4); 28 | public static final Integer m5 = new Integer(-5); 29 | public static final Integer m6 = new Integer(-6); 30 | public static final Integer m10 = new Integer(-10); 31 | 32 | /* 33 | * Fails with message "should throw exception". 34 | */ 35 | public void shouldThrow() { 36 | fail("Should throw exception"); 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/CacheWeakSoftRefTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Map; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | import static org.junit.Assert.assertTrue; 9 | 10 | public class CacheWeakSoftRefTest { 11 | 12 | /* TODO reenable 13 | 14 | @Test 15 | public void weak_htree_inserts_delete() throws InterruptedException { 16 | DB db = DBMaker 17 | .memoryDB() 18 | .cacheWeakRefEnable() 19 | .make(); 20 | testMap(db); 21 | } 22 | 23 | @Test 24 | public void soft_htree_inserts_delete() throws InterruptedException { 25 | DB db = DBMaker 26 | .memoryDB() 27 | .cacheSoftRefEnable() 28 | .make(); 29 | testMap(db); 30 | } 31 | 32 | 33 | private void testMap(DB db) throws InterruptedException { 34 | Map m = db.getHashMap("name"); 35 | for(Integer i = 0;i<1000;i++){ 36 | m.put(i,i); 37 | } 38 | Cache.WeakSoftRef engine = (Cache.WeakSoftRef)db.engine; 39 | assertTrue(engine.items.size()!=0); 40 | 41 | for(Integer i = 0;i<1000;i++){ 42 | Integer a = m.remove(i); 43 | assertEquals(i, a); 44 | } 45 | db.close(); 46 | int counter = 10000; 47 | while(engine.cleanerFinished.getCount()!=0 && counter>0){ 48 | Thread.sleep(1); 49 | counter--; 50 | } 51 | assertEquals(0,engine.cleanerFinished.getCount()); 52 | } 53 | */ 54 | } 55 | -------------------------------------------------------------------------------- /notice.txt: -------------------------------------------------------------------------------- 1 | MapDB 2 | Copyright 2012-2014 Jan Kotek 3 | 4 | This product includes software developed by Thomas Mueller and H2 group 5 | Relicensed under Apache License 2 with Thomas permission. 6 | (CompressLZF.java and EncryptionXTEA.java) 7 | Copyright (c) 2004-2011 H2 Group 8 | 9 | 10 | This product includes software developed by Doug Lea and JSR 166 group: 11 | (LongConcurrentMap.java, Atomic.java) 12 | * Written by Doug Lea with assistance from members of JCP JSR-166 13 | * Expert Group and released to the public domain, as explained at 14 | * http://creativecommons.org/licenses/publicdomain 15 | 16 | 17 | This product includes software developed for Apache Solr 18 | (LongConcurrentLRUMap.java) 19 | Copyright 2006-2014 The Apache Software Foundation 20 | 21 | This product includes software developed for Apache Harmony 22 | (LongHashMap.java) 23 | Copyright 2008-2012 The Apache Software Foundation 24 | 25 | 26 | This product includes software developed for Android project 27 | (SerializerPojo, a few lines to invoke constructor, see comments) 28 | //Copyright (C) 2012 The Android Open Source Project, licenced under Apache 2 license 29 | 30 | 31 | This product includes software developed by Heinz Kabutz for javaspecialists.eu 32 | (SerializerPojo, a few lines to invoke constructor, see comments) 33 | 2010-2014 Heinz Kabutz 34 | 35 | 36 | Some Map unit tests are from Google Collections. 37 | Credit goes to Jared Levy, George van den Driessche and other Google Collections developers. 38 | Copyright (C) 2007 Google Inc. 39 | 40 | Luc Peuvrier wrote some unit tests for ConcurrerentNavigableMap interface. 41 | 42 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/StoreTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.Random; 7 | 8 | import static org.junit.Assert.assertArrayEquals; 9 | import static org.junit.Assert.assertTrue; 10 | 11 | public class StoreTest { 12 | 13 | @Test public void compression(){ 14 | Store s = (Store)DBMaker.memoryDB() 15 | .transactionDisable() 16 | .compressionEnable() 17 | .makeEngine(); 18 | 19 | long size = s.getCurrSize(); 20 | long recid = s.put(new byte[10000],Serializer.BYTE_ARRAY); 21 | assertTrue(s.getCurrSize() - size < 200); 22 | assertTrue(Serializer.BYTE_ARRAY.equals(new byte[10000], s.get(recid, Serializer.BYTE_ARRAY))); 23 | } 24 | 25 | 26 | @Test public void compression_random(){ 27 | Random r = new Random(); 28 | 29 | for(int i=100;i<100000;i=i*2){ 30 | Store s = (Store)DBMaker.memoryDB() 31 | .transactionDisable() 32 | .compressionEnable() 33 | .makeEngine(); 34 | 35 | long size = s.getCurrSize(); 36 | byte[] b = new byte[i]; 37 | r.nextBytes(b); 38 | //grow so there is something to compress 39 | b = Arrays.copyOfRange(b,0,i); 40 | b = Arrays.copyOf(b,i*5); 41 | long recid = s.put(b,Serializer.BYTE_ARRAY); 42 | assertTrue(s.getCurrSize() - size < i*2+100); 43 | assertTrue(Serializer.BYTE_ARRAY.equals(b, s.get(recid, Serializer.BYTE_ARRAY))); 44 | } 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/examples/Histogram.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.Bind; 4 | import org.mapdb.DBMaker; 5 | import org.mapdb.Fun; 6 | import org.mapdb.HTreeMap; 7 | 8 | import java.util.concurrent.ConcurrentHashMap; 9 | import java.util.concurrent.ConcurrentMap; 10 | 11 | /** 12 | * Shows how to split map into categories and count elements in each category 13 | * 14 | * Here we show histogram of an {@code Math.random()}. 15 | * We represent category as string for clarity, but any number or other type could be used 16 | */ 17 | public class Histogram { 18 | 19 | public static void main(String[] args) { 20 | HTreeMap map = DBMaker.tempHashMap(); 21 | 22 | // histogram, category is a key, count is a value 23 | ConcurrentMap histogram = new ConcurrentHashMap(); //any map will do 24 | 25 | // bind histogram to primary map 26 | // we need function which returns category for each map entry 27 | Bind.histogram(map, histogram, new Fun.Function2(){ 28 | @Override 29 | public String run(Long key, Double value) { 30 | if(value<0.25) return "first quarter"; 31 | else if(value<0.5) return "second quarter"; 32 | else if(value<0.75) return "third quarter"; 33 | else return "fourth quarter"; 34 | } 35 | }); 36 | 37 | //insert some random stuff 38 | for(long key=0;key<1e4;key++){ 39 | map.put(key, Math.random()); 40 | } 41 | 42 | System.out.println(histogram); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/examples/MultiMap.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.BTreeKeySerializer; 4 | import org.mapdb.DB; 5 | import org.mapdb.DBMaker; 6 | import org.mapdb.Fun; 7 | 8 | import java.util.NavigableSet; 9 | 10 | /** 11 | * Shows howto implement MultiMap (Map with more then one values for a singe key) correctly. 12 | * To do 1:N mapping most people would use Map[String, List[Long]], however MapDB 13 | * requires nodes to be immutable, so this is wrong. 14 | */ 15 | public class MultiMap { 16 | 17 | public static void main(String[] args) { 18 | DB db = DBMaker.memoryDB().make(); 19 | 20 | // this is wrong, do not do it !!! 21 | // Map> map 22 | 23 | //correct way is to use composite set, where 'map key' is primary key and 'map value' is secondary value 24 | NavigableSet multiMap = db.treeSet("test"); 25 | 26 | //optionally you can use set with Delta Encoding. This may save lot of space 27 | multiMap = db.treeSetCreate("test2") 28 | .serializer(BTreeKeySerializer.ARRAY2) 29 | .make(); 30 | 31 | multiMap.add(new Object[]{"aa",1}); 32 | multiMap.add(new Object[]{"aa",2}); 33 | multiMap.add(new Object[]{"aa",3}); 34 | multiMap.add(new Object[]{"bb",1}); 35 | 36 | //find all values for a key 37 | for(Object[] l: Fun.filter(multiMap, "aa")){ 38 | System.out.println("value for key 'aa': "+l[1]); 39 | } 40 | 41 | //check if pair exists 42 | 43 | boolean found = multiMap.contains(new Object[]{"bb",1}); 44 | System.out.println("Found: " + found); 45 | 46 | db.close(); 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /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 | myapp.ui.level=ALL 25 | myapp.business.level=CONFIG 26 | myapp.data.level=SEVERE 27 | 28 | # Handlers 29 | java.util.logging.ConsoleHandler.level=ALL 30 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 31 | 32 | # --- FileHandler --- 33 | java.util.logging.FileHandler.level=ALL 34 | 35 | # Naming style for the output file: 36 | # (The output file is placed in the directory 37 | # defined by the "user.home" System property.) 38 | java.util.logging.FileHandler.pattern=%h/java%u.log 39 | 40 | # Limiting size of output file in bytes: 41 | java.util.logging.FileHandler.limit=500000 42 | 43 | # Number of output files to cycle through, by appending an 44 | # integer to the base file name: 45 | java.util.logging.FileHandler.count=1 46 | 47 | # Style of output (Simple or XML): 48 | java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue37Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.util.Iterator; 7 | import java.util.LinkedHashSet; 8 | import java.util.Set; 9 | import java.util.concurrent.ConcurrentMap; 10 | 11 | import static junit.framework.TestCase.assertEquals; 12 | import static org.junit.Assert.assertTrue; 13 | 14 | public class Issue37Test { 15 | 16 | 17 | 18 | @Test public void test3(){ 19 | 20 | DB db = DBMaker.memoryDirectDB().transactionDisable().asyncWriteFlushDelay(100).make(); 21 | ConcurrentMap orders = db.hashMapCreate("order").make(); 22 | for(int i = 0; i < 10000; i++) { 23 | orders.put((long)i, (long)i); 24 | } 25 | assertEquals(10000, orders.size()); 26 | 27 | 28 | int progress = 0; 29 | Set returned = new LinkedHashSet(); 30 | Iterator iter = orders.keySet().iterator(); 31 | while(iter.hasNext()) { 32 | Object key = iter.next(); 33 | 34 | if(returned.contains(key)) 35 | throw new AssertionError("already found: "+key); 36 | returned.add(key); 37 | progress++; 38 | assertTrue(progress <= 10000); 39 | } 40 | 41 | iter = orders.entrySet().iterator(); 42 | progress=0; 43 | while(iter.hasNext()) { 44 | progress++; 45 | iter.next(); 46 | assertTrue(progress <= 10000); 47 | } 48 | 49 | iter = orders.values().iterator(); 50 | progress=0; 51 | while(iter.hasNext()) { 52 | progress++; 53 | iter.next(); 54 | assertTrue(progress <= 10000); 55 | } 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue69Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.util.Map; 8 | 9 | import static org.junit.Assert.fail; 10 | 11 | /* 12 | * https://github.com/jankotek/MapDB/issues/69 13 | * 14 | * @author Konstantin Zadorozhny 15 | * 16 | */ 17 | public class Issue69Test { 18 | 19 | private DB db; 20 | 21 | @Before 22 | public void setUp() { 23 | db = DBMaker.tempFileDB() 24 | .transactionDisable() 25 | .checksumEnable() 26 | .deleteFilesAfterClose() 27 | .make(); 28 | } 29 | 30 | @After 31 | public void tearDown() throws InterruptedException { 32 | db.close(); 33 | } 34 | 35 | @Test 36 | public void testStackOverflowError() throws Exception { 37 | 38 | try{ 39 | Map map = db.hashMap("test"); 40 | 41 | StringBuilder buff = new StringBuilder(); 42 | 43 | long maxIterations = 1000000; 44 | int valueLength = 1024; 45 | long maxKeys = 1000; 46 | long i = 1; 47 | while (i < maxIterations) { 48 | 49 | if (i % 10000 == 0) { 50 | valueLength ++; 51 | // System.out.println("Iteration: " + i + "; Value length: " + valueLength); 52 | } 53 | 54 | String key = "key" + (int)(Math.random() * maxKeys); 55 | buff.setLength(valueLength); 56 | map.put(key, buff.toString()); 57 | 58 | i++; 59 | 60 | } 61 | }catch(Throwable e){ 62 | while(e!=null){ 63 | for(StackTraceElement ee: e.getStackTrace()){ 64 | System.out.println(ee); 65 | } 66 | System.out.println(); 67 | e = e.getCause(); 68 | } 69 | fail(); 70 | } 71 | 72 | 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/test/java/examples/CacheOffHeap.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.DBMaker; 4 | import org.mapdb.HTreeMap; 5 | import org.mapdb.Store; 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * This example shows how-to create off-heap cache, 11 | * where entries expire when maximal store size is reached. 12 | * 13 | * It also shows howto get basic statistics about store size. 14 | */ 15 | public class CacheOffHeap { 16 | 17 | public static void main(String[] args) { 18 | 19 | final double cacheSizeInGB = 1.0; 20 | 21 | // Create cache backed by off-heap store 22 | // In this case store will use ByteBuffers backed by byte[]. 23 | HTreeMap cache = DBMaker.newCache(cacheSizeInGB); 24 | 25 | // Other alternative is to use Direct ByteBuffers. 26 | // In this case the memory is not released if cache is not correctly closed. 27 | 28 | // cache = DBMaker.newCacheDirect(cacheSizeInGB); 29 | 30 | //generates random key and values 31 | Random r = new Random(); 32 | //used to print store statistics 33 | Store store = Store.forEngine(cache.getEngine()); 34 | 35 | 36 | // insert some stuff in cycle 37 | for(long counter=1; counter<1e8; counter++){ 38 | long key = r.nextLong(); 39 | byte[] value = new byte[1000]; 40 | r.nextBytes(value); 41 | 42 | cache.put(key,value); 43 | 44 | if(counter%1e5==0){ 45 | System.out.printf("Map size: %,d, counter %,d, store size: %,d, store free size: %,d\n", 46 | cache.sizeLong(), counter, store.getCurrSize(), store.getFreeSize()); 47 | } 48 | 49 | } 50 | 51 | // and close to release memory (optional) 52 | cache.getEngine().close(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue418Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.File; 6 | import java.util.Set; 7 | 8 | import static org.junit.Assert.assertArrayEquals; 9 | import static org.junit.Assert.assertTrue; 10 | 11 | public class Issue418Test { 12 | 13 | @Test 14 | public void test(){ 15 | final File tmp = UtilsTest.tempDbFile(); 16 | 17 | long[] expireHeads = null; 18 | long[] expireTails = null; 19 | for (int o = 0; o < 2; o++) { 20 | final DB db = DBMaker.fileDB(tmp).transactionDisable().make(); 21 | final HTreeMap map = db.hashMapCreate("foo").expireMaxSize(100).makeOrGet(); 22 | 23 | if(expireHeads!=null) 24 | assertTrue(Serializer.LONG_ARRAY.equals(expireHeads, map.expireHeads)); 25 | else 26 | expireHeads = map.expireHeads; 27 | 28 | if(expireTails!=null) 29 | assertTrue(Serializer.LONG_ARRAY.equals(expireTails, map.expireTails)); 30 | else 31 | expireTails = map.expireTails; 32 | 33 | 34 | 35 | for (int i = 0; i < 1000; i++) 36 | map.put("foo" + i, "bar" + i); 37 | 38 | 39 | db.commit(); 40 | db.close(); 41 | } 42 | } 43 | 44 | 45 | @Test 46 | public void test_set(){ 47 | final File tmp = UtilsTest.tempDbFile(); 48 | 49 | for (int o = 0; o < 2; o++) { 50 | final DB db = DBMaker.fileDB(tmp).transactionDisable().make(); 51 | final Set map = db.hashSetCreate("foo").expireMaxSize(100).makeOrGet(); 52 | 53 | for (int i = 0; i < 1000; i++) 54 | map.add("foo" + i); 55 | 56 | db.commit(); 57 | db.close(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue86Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.Serializable; 6 | import java.util.Map; 7 | 8 | /* 9 | * 10 | * @author M.Y. Developers 11 | */ 12 | public class Issue86Test { 13 | public static DB createFileStore() { 14 | return DBMaker 15 | .tempFileDB() 16 | .transactionDisable() 17 | .make(); 18 | } 19 | 20 | @Test 21 | public void Array() { 22 | DB createFileStore = createFileStore(); 23 | Map map = createFileStore.treeMap("testMap"); 24 | int maxSize = 1000; 25 | for (int i = 1; i < maxSize; i++) { 26 | String[] array = new String[i]; 27 | for (int j = 0; j < i; j++) { 28 | array[j] = UtilsTest.randomString(100); 29 | } 30 | map.put(i, array); 31 | } 32 | } 33 | 34 | @Test 35 | public void FieldArray() { 36 | DB createFileStore = createFileStore(); 37 | Map map = createFileStore.treeMap("testMap"); 38 | int maxSize = 1000; 39 | for (int i = 1; i < maxSize; i++) { 40 | map.put(i, new StringContainer(i)); 41 | } 42 | } 43 | 44 | private static class StringContainer implements Serializable { 45 | 46 | public String[] container; 47 | 48 | public StringContainer() { 49 | } 50 | 51 | public String[] getContainer() { 52 | return container; 53 | } 54 | 55 | public void setContainer(String[] container) { 56 | this.container = container; 57 | } 58 | 59 | public StringContainer(int size) { 60 | container = new String[size]; 61 | for (int i = 0; i < size; i++) { 62 | container[i] = UtilsTest.randomString(100); 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/examples/Compression.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.DB; 4 | import org.mapdb.DBMaker; 5 | import org.mapdb.Serializer; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * Demonstrates how-to apply compression in various modes. 11 | *

12 | * MapDB uses LZF compression, there is discussion to support other compression alghorithms 13 | * 14 | */ 15 | public class Compression { 16 | 17 | public static void main(String[] args) { 18 | /* 19 | * first case, just enable storage wide compression for all records. 20 | */ 21 | DB db = DBMaker.memoryDB() 22 | .compressionEnable() //this settings enables compression 23 | .make(); 24 | //and now create and use map as usual 25 | Map map = db.treeMap("test"); 26 | map.put("some","stuff"); 27 | 28 | 29 | 30 | /* 31 | * Other option is to use compression only for specific part. For example if 32 | * you have large values, you may want to compress them. It may make sense 33 | * not to compress BTree Nodes and Keys. 34 | */ 35 | DB db2 = DBMaker.memoryDB().make(); //no store wide compression this time 36 | 37 | //construct value serializier, use default serializier 38 | Serializer valueSerializer = db2.getDefaultSerializer(); 39 | //but wrap it, to compress its output 40 | valueSerializer = new Serializer.CompressionWrapper(valueSerializer); 41 | 42 | //now construct map, with additional options 43 | Map map2 = db2.treeMapCreate("test") 44 | .valuesOutsideNodesEnable() // store values outside of BTree Nodes. Faster reads if values are large. 45 | .valueSerializer(valueSerializer) //set our value serializer. 46 | .make(); 47 | 48 | map2.put("some","stuff"); 49 | 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue183Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.*; 6 | import java.util.Map; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class Issue183Test { 11 | 12 | @Test 13 | public void main(){ 14 | 15 | File f = UtilsTest.tempDbFile(); 16 | 17 | Map map1; 18 | 19 | TxMaker txMaker = DBMaker 20 | .fileDB(f) 21 | .closeOnJvmShutdown() 22 | .makeTxMaker(); 23 | 24 | DB db = txMaker.makeTx(); 25 | 26 | map1 = db.treeMapCreate("map1") 27 | .valueSerializer(new StringSerializer()) 28 | .makeOrGet(); 29 | 30 | map1.put("foo", "bar"); 31 | db.commit(); 32 | db.close(); 33 | txMaker.close(); 34 | 35 | 36 | txMaker = DBMaker 37 | .fileDB(f) 38 | .closeOnJvmShutdown() 39 | .makeTxMaker(); 40 | 41 | db = txMaker.makeTx(); 42 | 43 | map1 = db.treeMapCreate("map1") 44 | .valueSerializer(new StringSerializer()) 45 | .makeOrGet(); 46 | 47 | assertEquals("bar", map1.get("foo")); 48 | map1.put("foo2", "bar2"); 49 | db.commit(); 50 | db.close(); 51 | txMaker.close(); 52 | 53 | } 54 | 55 | private static final class StringSerializer extends Serializer implements Serializable { 56 | 57 | private static final long serialVersionUID = -8356516782418439492L; 58 | 59 | @Override 60 | public void serialize(DataOutput out, String value) throws IOException { 61 | out.writeUTF(value); 62 | } 63 | 64 | @Override 65 | public String deserialize(DataInput in, int available) throws IOException { 66 | return in.readUTF(); 67 | } 68 | 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue77Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.After; 5 | import org.junit.Test; 6 | 7 | import java.io.File; 8 | import java.util.Random; 9 | import java.util.concurrent.ConcurrentNavigableMap; 10 | 11 | public class Issue77Test { 12 | private Random random = new Random(1); 13 | private File dir = new File(UtilsTest.tempDbFile()+"aaa"); 14 | 15 | @Test 16 | public void run(){ 17 | create(); 18 | read(); // UnsupportedOperationException 19 | read(); // InternalError 20 | } 21 | 22 | DB open(boolean readOnly) { 23 | // This works: 24 | // DBMaker maker = DBMaker.fileDB(new File(dir + "/test")); 25 | // This is faster, but fails if read() is called for the second time: 26 | DBMaker.Maker maker = DBMaker.appendFileDB(new File(dir + "/test")); 27 | if (readOnly) { 28 | maker.readOnly(); 29 | } 30 | // maker.randomAccessFileEnableIfNeeded(); 31 | maker.closeOnJvmShutdown(); 32 | DB db = maker.make(); // InternalError, UnsupportedOperationException 33 | return db; 34 | } 35 | 36 | void create() { 37 | dir.mkdirs(); 38 | DB db = open(false); 39 | ConcurrentNavigableMap map = db.treeMap("bytes"); 40 | int n = 10; 41 | int m = 10; 42 | for (int i = 0; i < n; i++) { 43 | map.put(i, getRandomData(m)); 44 | } 45 | db.commit(); 46 | db.close(); 47 | } 48 | 49 | void read() { 50 | DB db = open(true); // InternalError, UnsupportedOperationException 51 | db.close(); 52 | } 53 | 54 | byte[] getRandomData(int n) { 55 | byte[] c = new byte[n]; 56 | random.nextBytes(c); 57 | return c; 58 | } 59 | 60 | @After 61 | public void cleanup(){ 62 | for (File f : dir.listFiles()) { 63 | f.delete(); 64 | } 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/StoreLongLongMapTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import java.util.Random; 9 | 10 | public class StoreLongLongMapTest { 11 | 12 | @Test public void sequentialUpdates(){ 13 | Map h = new HashMap(); 14 | Store.LongLongMap m = new Store.LongLongMap(); 15 | 16 | 17 | for(long i=1;i<10000L;i++){ 18 | h.put(i,i*2); 19 | m.put(i, i * 2); 20 | } 21 | 22 | for(Map.Entry e:h.entrySet()){ 23 | assertEquals(e.getValue(), new Long(m.get(e.getKey()))); 24 | } 25 | 26 | assertEquals(m.size(), h.size()); 27 | 28 | long[] t = m.table; 29 | for(int i=0;i h = new HashMap(); 41 | Store.LongLongMap m = new Store.LongLongMap(); 42 | 43 | 44 | for(long i=1;i<10000L;i++){ 45 | h.put(i,i*2); 46 | m.put(i, i * 2); 47 | } 48 | for(long i=1;i<10000L;i++){ 49 | h.put(i,i*3); 50 | m.put(i, i * 3); 51 | } 52 | 53 | 54 | 55 | for(Map.Entry e:h.entrySet()){ 56 | assertEquals(e.getValue(), new Long(m.get(e.getKey()))); 57 | } 58 | 59 | assertEquals(m.size(), h.size()); 60 | 61 | long[] t = m.table; 62 | for(int i=0;i h = new HashMap(); 15 | Store.LongObjectMap m = new Store.LongObjectMap(); 16 | 17 | 18 | for(long i=1;i<10000L;i++){ 19 | h.put(i,i*2); 20 | m.put(i, i * 2); 21 | } 22 | 23 | for(Map.Entry e:h.entrySet()){ 24 | assertEquals(e.getValue(), new Long(m.get(e.getKey()))); 25 | } 26 | 27 | assertEquals(m.size, h.size()); 28 | 29 | long[] t = m.set; 30 | for(int i=0;i h = new HashMap(); 42 | Store.LongObjectMap m = new Store.LongObjectMap(); 43 | 44 | 45 | for(long i=1;i<10000L;i++){ 46 | h.put(i,i*2); 47 | m.put(i, i * 2); 48 | } 49 | for(long i=1;i<10000L;i++){ 50 | h.put(i,i*3); 51 | m.put(i, i * 3); 52 | } 53 | 54 | 55 | 56 | for(Map.Entry e:h.entrySet()){ 57 | assertEquals(e.getValue(), new Long(m.get(e.getKey()))); 58 | } 59 | 60 | assertEquals(m.size, h.size()); 61 | 62 | long[] t = m.set; 63 | for(int i=0;i map; 26 | 27 | 28 | @Override 29 | protected void setUp() throws Exception { 30 | r = DBMaker.memoryDB().transactionDisable().makeEngine(); 31 | map = new BTreeMap( 32 | r,false, 33 | createRootRef(r,BASIC, Serializer.BASIC,0), 34 | 6, valsOutsideNodes, 0, BASIC, valueSerializer, 0); 35 | } 36 | 37 | 38 | @After 39 | public void close(){ 40 | r.close(); 41 | } 42 | 43 | /* 44 | * When valsOutsideNodes is true should not deserialize value during .containsKey 45 | */ 46 | public void testContainsKeySkipsValueDeserialisation() { 47 | 48 | map.put(1, "abc"); 49 | 50 | boolean contains = map.containsKey(1); 51 | 52 | assertEquals(true, contains ); 53 | assertEquals("Deserialize was called", !valsOutsideNodes, valueSerializer.isDeserializeCalled() ); 54 | } 55 | 56 | static class RecordingSerializer extends SerializerBase implements Serializable { 57 | 58 | private static final long serialVersionUID = 1L; 59 | private boolean deserializeCalled = false; 60 | 61 | @Override 62 | public Object deserialize(DataInput is, int capacity) throws IOException { 63 | deserializeCalled = true; 64 | return super.deserialize(is, capacity); 65 | } 66 | 67 | public boolean isDeserializeCalled() { 68 | return deserializeCalled; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/examples/CacheEntryExpiry.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.DB; 4 | import org.mapdb.DBMaker; 5 | import org.mapdb.HTreeMap; 6 | import org.mapdb.Store; 7 | 8 | import java.util.Random; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | 12 | /** 13 | * HTreeMap (HashMap) can be used as cache, where items are removed after timeout or when maximal size is reached. 14 | * 15 | * 16 | */ 17 | public class CacheEntryExpiry { 18 | 19 | 20 | 21 | public static void main(String[] args) { 22 | //init off-heap store with 2GB size limit 23 | DB db = DBMaker 24 | .memoryDirectDB() //use off-heap memory, on-heap is `.memoryDB()` 25 | .transactionDisable() //better performance 26 | .make(); 27 | 28 | //create map, entries are expired if not accessed (get,iterate) for 10 seconds or 30 seconds after 'put' 29 | //There is also maximal size limit to prevent OutOfMemoryException 30 | HTreeMap map = db 31 | .hashMapCreate("cache") 32 | .expireMaxSize(1000000) 33 | .expireAfterWrite(30, TimeUnit.SECONDS) 34 | .expireAfterAccess(10, TimeUnit.SECONDS) 35 | .make(); 36 | 37 | //load stuff 38 | for(int i = 0;i<100000;i++){ 39 | map.put(i, randomString(1000)); 40 | } 41 | 42 | //one can monitor two space usage numbers: 43 | 44 | //free space in store 45 | long freeSize = Store.forDB(db).getFreeSize(); 46 | 47 | //current size of store (how much memory it has allocated 48 | long currentSize = Store.forDB(db).getCurrSize(); 49 | 50 | 51 | } 52 | 53 | 54 | public static String randomString(int size) { 55 | String chars = "0123456789abcdefghijklmnopqrstuvwxyz !@#$%^&*()_+=-{}[]:\",./<>?|\\"; 56 | StringBuilder b = new StringBuilder(size); 57 | Random r = new Random(); 58 | for(int i=0;i set = db.treeSetCreate("set").makeOrGet(); 49 | set.clear(); 50 | 51 | set.add(testEnumValue); 52 | db.commit(); 53 | 54 | db.close(); 55 | 56 | db = DBMaker.fileDB(f).make(); 57 | 58 | set = db.treeSetCreate("set").makeOrGet(); 59 | AdvancedEnum enumValue = (AdvancedEnum)set.iterator().next(); 60 | 61 | Assert.assertNotNull(enumValue); 62 | 63 | assertEquals("Invalid Enum.name()", enumValue.name(), testEnumValue.name()); 64 | assertEquals("Invalid Enum.ordinal()", enumValue.ordinal(), testEnumValue.ordinal()); 65 | } 66 | 67 | @Test public void testEnum2(){ 68 | assertEquals(AdvancedEnum.A, AdvancedEnum.class.getEnumConstants()[0]); 69 | 70 | 71 | DB db = DBMaker.memoryDB().make(); 72 | AdvancedEnum a = (AdvancedEnum) UtilsTest.clone(AdvancedEnum.A, db.getDefaultSerializer()); 73 | assertEquals(a.toString(),AdvancedEnum.A.toString()); 74 | assertEquals(a.ordinal(),AdvancedEnum.A.ordinal()); 75 | 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /src/test/java/examples/Secondary_Values.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.*; 4 | 5 | import java.io.Serializable; 6 | import java.util.NavigableSet; 7 | 8 | /** 9 | * Example demonstrate 1:N relation between two collections. 10 | * Secondary set is updated automatically when primary map is modified. 11 | */ 12 | public class Secondary_Values { 13 | 14 | /** 15 | * Each Person class contains name and coma-separated string of friend names 16 | */ 17 | static class Person implements Serializable{ 18 | final int id; 19 | final String name; 20 | //coma separated list of friends 21 | final String friends; 22 | 23 | Person(int id, String name, String friends) { 24 | this.id = id; 25 | this.name = name; 26 | this.friends = friends; 27 | } 28 | } 29 | 30 | public static void main(String[] args) { 31 | DB db = DBMaker.memoryDB().make(); 32 | //list if friends 33 | BTreeMap friends = db.treeMap("friends"); 34 | 35 | //secondary collections which lists all friends for given id 36 | NavigableSet id2friends = db.treeSetCreate("id2friends") 37 | .serializer(BTreeKeySerializer.ARRAY2) 38 | .makeOrGet(); 39 | 40 | //keep secondary synchronized with primary 41 | Bind.secondaryValues(friends,id2friends, new Fun.Function2() { 42 | @Override 43 | public String[] run(Integer integer, Person person) { 44 | return person.friends.split(","); 45 | } 46 | }); 47 | 48 | //add into primary 49 | friends.put(1, new Person(1,"John","Karin,Peter")); 50 | friends.put(2, new Person(2,"Karin","Peter")); 51 | //secondary now contains [1,Karin], [1,Peter], [2,Peter] 52 | System.out.println(id2friends); 53 | 54 | //list all friends associated with John. This does range query on NavigableMap 55 | for(Object[] k:Fun.filter(id2friends, 1)){ 56 | String name = (String) k[1]; 57 | System.out.println(name); 58 | } 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue89Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.File; 8 | import java.util.NavigableSet; 9 | 10 | public class Issue89Test { 11 | 12 | 13 | private static final String MY_TEST_DATA_FILE = UtilsTest.tempDbFile().getAbsolutePath(); 14 | private static final String MAP_DB_DATA_FILE_TO_REMOVE = MY_TEST_DATA_FILE + ".0"; 15 | private static final String TEST_TREE_SET = "TestTreeSet"; 16 | private static final String DUMMY_CONTENT = "DummyContent"; 17 | 18 | 19 | @Before 20 | public void setUp() throws Exception { 21 | deleteFile(); 22 | } 23 | 24 | @After 25 | public void tearDown() throws Exception { 26 | deleteFile(); 27 | } 28 | 29 | 30 | @Test 31 | public void testAppend() throws Exception { 32 | appendToDataFile(); 33 | appendToDataFile(); 34 | appendToDataFile(); 35 | appendToDataFile(); 36 | } 37 | 38 | 39 | private void appendToDataFile() { 40 | final DB myTestDataFile = createMapDB(MY_TEST_DATA_FILE); 41 | addData(myTestDataFile); 42 | myTestDataFile.close(); 43 | } 44 | 45 | 46 | private void addData(DB myTestDataFile) { 47 | final NavigableSet testTreeSet = myTestDataFile.treeSet(TEST_TREE_SET); 48 | testTreeSet.add(DUMMY_CONTENT); 49 | myTestDataFile.commit(); 50 | 51 | } 52 | 53 | 54 | private DB createMapDB(String fileName) { 55 | final File file = new File(fileName); 56 | return createMapDB(file); 57 | } 58 | 59 | 60 | private DB createMapDB(File file) { 61 | return DBMaker.appendFileDB(file) 62 | .closeOnJvmShutdown() 63 | .make(); 64 | } 65 | 66 | 67 | private void deleteFile() { 68 | final File file = new File(MAP_DB_DATA_FILE_TO_REMOVE); 69 | if (file.exists()) { 70 | file.delete(); 71 | } 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/CompressTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.IOException; 8 | 9 | import static org.junit.Assert.*; 10 | 11 | public class CompressTest{ 12 | 13 | DB db; 14 | 15 | @Before public void init(){ 16 | db = DBMaker 17 | .memoryDB() 18 | .transactionDisable() 19 | .compressionEnable() 20 | .make(); 21 | } 22 | 23 | 24 | @After 25 | public void close(){ 26 | db.close(); 27 | } 28 | 29 | @Test 30 | public void check_instance() throws Exception { 31 | Store s = Store.forDB(db); 32 | assertTrue(s.compress); 33 | } 34 | 35 | 36 | @Test 37 | public void put_get_update() throws Exception { 38 | long recid = db.engine.put("aaaa", Serializer.STRING_NOSIZE); 39 | assertEquals("aaaa",db.engine.get(recid, Serializer.STRING_NOSIZE)); 40 | db.engine.update(recid, "bbbb", Serializer.STRING_NOSIZE); 41 | assertEquals("bbbb",db.engine.get(recid, Serializer.STRING_NOSIZE)); 42 | db.engine.delete(recid,Serializer.STRING_NOSIZE); 43 | assertEquals(null,db.engine.get(recid, Serializer.STRING_NOSIZE)); 44 | 45 | } 46 | 47 | 48 | @Test 49 | public void short_compression() throws Exception { 50 | byte[] b = new byte[]{1,2,3,4,5,33,3}; 51 | byte[] b2 = UtilsTest.clone(b, new Serializer.CompressionWrapper(Serializer.BYTE_ARRAY)); 52 | assertTrue(Serializer.BYTE_ARRAY.equals(b, b2)); 53 | } 54 | 55 | @Test public void large_compression() throws IOException { 56 | byte[] b = new byte[1024]; 57 | b[0] = 1; 58 | b[4] = 5; 59 | b[1000] = 1; 60 | 61 | Serializer ser = new Serializer.CompressionWrapper(Serializer.BYTE_ARRAY); 62 | assertTrue(Serializer.BYTE_ARRAY.equals(b, UtilsTest.clone(b, ser))); 63 | 64 | //check compressed size is actually smaller 65 | DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); 66 | ser.serialize(out,b); 67 | assertTrue(out.pos<100); 68 | } 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/examples/CacheOffHeapAdvanced.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.*; 4 | 5 | import java.util.Random; 6 | 7 | /** 8 | * This example shows how-to create off-heap cache, 9 | * where entries expire when maximal store size is reached. 10 | * 11 | * It also shows howto get basic statistics about store size. 12 | * 13 | * It is more advanced version of previous example. 14 | * It uses more settings, bypasses general serialization for best performance 15 | * and discussed other performance tunning 16 | * 17 | */ 18 | public class CacheOffHeapAdvanced { 19 | 20 | public static void main(String[] args) { 21 | 22 | final double cacheSizeInGB = 1.0; 23 | 24 | //first create store 25 | DB db = DBMaker 26 | .memoryDirectDB() 27 | .transactionDisable() 28 | //some additional options for DB 29 | // .asyncWriteEnable() 30 | // .cacheSize(100000) 31 | .make(); 32 | 33 | 34 | HTreeMap cache = db 35 | .hashMapCreate("cache") 36 | .expireStoreSize(cacheSizeInGB) 37 | .counterEnable() //disable this if cache.size() is not used 38 | //use proper serializers to and improve performance 39 | .keySerializer(Serializer.LONG) 40 | .valueSerializer(Serializer.BYTE_ARRAY) 41 | .make(); 42 | 43 | 44 | //generates random key and values 45 | Random r = new Random(); 46 | //used to print store statistics 47 | Store store = Store.forDB(db); 48 | 49 | 50 | // insert some stuff in cycle 51 | for(long counter=1; counter<1e8; counter++){ 52 | long key = r.nextLong(); 53 | byte[] value = new byte[1000]; 54 | r.nextBytes(value); 55 | 56 | cache.put(key,value); 57 | 58 | if(counter%1e5==0){ 59 | System.out.printf("Map size: %,d, counter %,d, curr store size: %,d, store free size: %,d\n", 60 | cache.sizeLong(), counter, store.getCurrSize(), store.getFreeSize()); 61 | } 62 | 63 | } 64 | 65 | // and close to release memory 66 | db.close(); 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/ExamplesTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import examples.*; 5 | import org.junit.Test; 6 | 7 | import java.io.IOException; 8 | 9 | public class ExamplesTest { 10 | 11 | static final String[] args= new String[0]; 12 | 13 | @Test public void _HelloWorld() throws IOException { 14 | _HelloWorld.main(args); 15 | } 16 | 17 | @Test public void _TempMap(){ 18 | _TempMap.main(args); 19 | } 20 | 21 | @Test public void Cache(){ 22 | CacheEntryExpiry.main(args); 23 | } 24 | 25 | @Test public void Compression(){ 26 | Compression.main(args); 27 | } 28 | 29 | @Test public void Huge_Insert() throws IOException { 30 | Huge_Insert.main(args); 31 | } 32 | 33 | 34 | 35 | @Test public void Custom_Value() throws IOException { 36 | Custom_Value.main(args); 37 | } 38 | 39 | 40 | @Test public void Bidi_Map(){ 41 | Bidi_Map.main(args); 42 | } 43 | 44 | @Test public void Histogram(){ 45 | Histogram.main(args); 46 | } 47 | 48 | @Test public void Lazily_Loaded_Records(){ 49 | Lazily_Loaded_Records.main(args); 50 | } 51 | 52 | @Test public void Map_Size_Counter(){ 53 | Map_Size_Counter.main(args); 54 | } 55 | 56 | @Test public void MultiMap(){ 57 | MultiMap.main(args); 58 | } 59 | 60 | @Test public void Secondary_Key(){ 61 | Secondary_Key.main(args); 62 | } 63 | 64 | @Test public void Secondary_Map(){ 65 | Secondary_Map.main(args); 66 | } 67 | 68 | @Test public void Secondary_Values(){ 69 | Secondary_Values.main(args); 70 | } 71 | 72 | @Test public void SQL_Auto_Incremental_Unique_Key(){ 73 | SQL_Auto_Incremental_Unique_Key.main(args); 74 | } 75 | 76 | @Test public void Transactions(){ 77 | Transactions.main(args); 78 | } 79 | 80 | @Test public void Transactions2(){ 81 | Transactions2.main(args); 82 | } 83 | 84 | @Test public void TreeMap_Composite_Key(){ 85 | TreeMap_Composite_Key.main(args); 86 | } 87 | 88 | @Test public void Pump_InMemory_Import_Than_Save_To_Disk(){ 89 | Pump_InMemory_Import_Then_Save_To_Disk.main(args); 90 | } 91 | 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/FunTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.*; 7 | import static org.mapdb.Fun.*; 8 | 9 | @SuppressWarnings({ "unchecked", "rawtypes" }) 10 | public class FunTest { 11 | 12 | public int compare(int[] o1, int[] o2) { 13 | for(int i = 0;io2[i]) return 1; 16 | } 17 | return 0; 18 | } 19 | 20 | 21 | final Object[] vals = new Object[]{ "A", "B", "C",}; 22 | 23 | @Test public void t2_equals(){ 24 | assertEquals(new Pair("A","B"), new Pair("A","B")); 25 | assertEquals(new Pair("A",null), new Pair("A",null)); 26 | assertFalse(new Pair("A","B").equals(new Pair("A","C"))); 27 | } 28 | 29 | @Test public void t2_compare(){ 30 | 31 | for(int a=0;ac || (a==c && b>d)) 49 | assertTrue(i>0); 50 | 51 | } 52 | } 53 | } 54 | } 55 | } 56 | 57 | 58 | 59 | 60 | @Test public void byte_array_comparator(){ 61 | byte[] b1 = new byte[]{1,1}; 62 | byte[] b1_ = new byte[]{1,1}; 63 | byte[] b2 = new byte[]{1,2}; 64 | byte[] blong = new byte[]{1,2,3}; 65 | assertEquals(-1, Fun.BYTE_ARRAY_COMPARATOR.compare(b1,b2)); 66 | assertEquals(-1, Fun.BYTE_ARRAY_COMPARATOR.compare(b2,blong)); 67 | assertEquals(1, Fun.BYTE_ARRAY_COMPARATOR.compare(b2,b1)); 68 | assertEquals(0, Fun.BYTE_ARRAY_COMPARATOR.compare(b1,b1)); 69 | assertEquals(0, Fun.BYTE_ARRAY_COMPARATOR.compare(b1,b1_)); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/examples/Lazily_Loaded_Records.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.Atomic; 4 | import org.mapdb.DB; 5 | import org.mapdb.DBMaker; 6 | import org.mapdb.Serializer; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * All collections are loaded lazily by default. 12 | * MapDB never loads full collection into heap memory, 13 | * only small currently used portion (typically single tree node) is loaded into heap. 14 | * But even single tree node can be too large (for example 32 key-value pairs), 15 | * and you may want to load even single values lazily. 16 | * 17 | */ 18 | public class Lazily_Loaded_Records { 19 | 20 | public static void main(String[] args) { 21 | 22 | DB db = DBMaker.memoryDB().make(); 23 | // 24 | // TreeMap has build in support for lazily loaded values. 25 | // In that case each value are not stored inside node, 26 | // but in separate record. 27 | // 28 | // use DB.createTreeMap to create TreeMap with non-default parameters 29 | 30 | 31 | Map map = db.treeMapCreate("name").valuesOutsideNodesEnable().make(); 32 | map.put("key","this string is loaded lazily with 'map.get(key)' "); 33 | 34 | 35 | // 36 | // Other option for lazily loaded record is to use Atomic.Var. 37 | // In this case you have singleton record with name. 38 | // As bonus you can update reference in thread-safe atomic manner. 39 | // 40 | Atomic.Var record = 41 | db.atomicVarCreate("lazyRecord", "aaa", db.getDefaultSerializer()); 42 | 43 | record.set("some value"); 44 | System.out.println(record.get()); 45 | 46 | 47 | // Last option is to use low level Engine storage directly. 48 | // Each stored record gets assigned unique recid (record id), 49 | // which is latter used to get or update record. 50 | // Your code should store only recid as reference to object. 51 | // All MapDB collections are written this way. 52 | 53 | //insert new record 54 | long recid = db.getEngine().put("something", Serializer.STRING_NOSIZE); 55 | 56 | //load record 57 | String lazyString = db.getEngine().get(recid, Serializer.STRING_NOSIZE); 58 | 59 | //update record 60 | db.getEngine().update(recid, "new value", Serializer.STRING_NOSIZE); 61 | 62 | 63 | //I hope this example helped! 64 | db.close(); 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue241.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.File; 6 | import java.io.Serializable; 7 | import java.util.Map; 8 | 9 | public class Issue241 10 | { 11 | @Test 12 | public void main() 13 | { 14 | DB db = getDb(); 15 | final String mapName = "map"; //$NON-NLS-1$ 16 | Map map = db.treeMapCreate(mapName).make(); 17 | // db.createTreeMap(mapName) 18 | // .valueSerializer(new CustomSerializer()).make(); 19 | map.put(1L, new CustomClass("aString", 1001L)); //$NON-NLS-1$ 20 | db.commit(); 21 | db.close(); 22 | 23 | db = getDb(); 24 | map = db.treeMap(mapName); 25 | map.get(1L); 26 | } 27 | 28 | private static DB getDb() 29 | { 30 | final File dbFile = UtilsTest.tempDbFile(); 31 | return DBMaker.appendFileDB(dbFile).make(); 32 | } 33 | 34 | private static final class CustomClass implements Serializable 35 | { 36 | private final String aString; 37 | private final Long aLong; 38 | 39 | private CustomClass(String aString, Long aLong) 40 | { 41 | this.aString = aString; 42 | this.aLong = aLong; 43 | } 44 | 45 | private String getaString() 46 | { 47 | return aString; 48 | } 49 | 50 | private Long getaLong() 51 | { 52 | return aLong; 53 | } 54 | } 55 | 56 | // public static final class CustomSerializer implements Serializer, Serializable 57 | // { 58 | // @Override 59 | // public void serialize(DataOutput out, CustomClass value) throws IOException 60 | // { 61 | // out.writeLong(value.getaLong()); 62 | // final byte[] stringBytes = value.getaString().getBytes(); 63 | // out.writeInt(stringBytes.length); 64 | // out.write(stringBytes); 65 | // } 66 | // 67 | // @Override 68 | // public CustomClass deserialize(DataInput in, int available) throws IOException 69 | // { 70 | // final Long theLong = in.readLong(); 71 | // final int stringBytesLength = in.readInt(); 72 | // final byte[] stringBytes = new byte[stringBytesLength]; 73 | // in.readFully(stringBytes); 74 | // return new CustomClass(new String(stringBytes), theLong); 75 | // } 76 | // } 77 | } 78 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Serialized2DerivedBean.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | public class Serialized2DerivedBean extends Serialization2Bean { 4 | private static final long serialVersionUID = 2071817382135925585L; 5 | 6 | private String d1 = "1"; 7 | private String d2 = "2"; 8 | private String d3 = null; 9 | private String d4 = "4"; 10 | private String d5 = null; 11 | private String d6 = "6"; 12 | 13 | @Override 14 | public int hashCode() { 15 | final int prime = 31; 16 | int result = super.hashCode(); 17 | result = prime * result + ((d1 == null) ? 0 : d1.hashCode()); 18 | result = prime * result + ((d2 == null) ? 0 : d2.hashCode()); 19 | result = prime * result + ((d3 == null) ? 0 : d3.hashCode()); 20 | result = prime * result + ((d4 == null) ? 0 : d4.hashCode()); 21 | result = prime * result + ((d5 == null) ? 0 : d5.hashCode()); 22 | result = prime * result + ((d6 == null) ? 0 : d6.hashCode()); 23 | return result; 24 | } 25 | 26 | @Override 27 | public boolean equals(Object obj) { 28 | if (this == obj) 29 | return true; 30 | if (!super.equals(obj)) 31 | return false; 32 | if (getClass() != obj.getClass()) 33 | return false; 34 | Serialized2DerivedBean other = (Serialized2DerivedBean) obj; 35 | if (d1 == null) { 36 | if (other.d1 != null) 37 | return false; 38 | } else if (!d1.equals(other.d1)) 39 | return false; 40 | if (d2 == null) { 41 | if (other.d2 != null) 42 | return false; 43 | } else if (!d2.equals(other.d2)) 44 | return false; 45 | if (d3 == null) { 46 | if (other.d3 != null) 47 | return false; 48 | } else if (!d3.equals(other.d3)) 49 | return false; 50 | if (d4 == null) { 51 | if (other.d4 != null) 52 | return false; 53 | } else if (!d4.equals(other.d4)) 54 | return false; 55 | if (d5 == null) { 56 | if (other.d5 != null) 57 | return false; 58 | } else if (!d5.equals(other.d5)) 59 | return false; 60 | if (d6 == null) { 61 | if (other.d6 != null) 62 | return false; 63 | } else if (!d6.equals(other.d6)) 64 | return false; 65 | return true; 66 | } 67 | 68 | 69 | 70 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/MapListenerTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.concurrent.atomic.AtomicInteger; 6 | import java.util.concurrent.atomic.AtomicReference; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | import static org.junit.Assert.assertTrue; 10 | 11 | @SuppressWarnings({"rawtypes","unchecked"}) 12 | public class MapListenerTest { 13 | 14 | @Test public void hashMap(){ 15 | tt(DBMaker.memoryDB().transactionDisable().cacheHashTableEnable().make().hashMap("test")); 16 | } 17 | 18 | @Test public void treeMap(){ 19 | tt(DBMaker.memoryDB().transactionDisable().cacheHashTableEnable().make().treeMap("test")); 20 | } 21 | 22 | 23 | void tt(Bind.MapWithModificationListener m){ 24 | final AtomicReference key = new AtomicReference(null); 25 | final AtomicReference newVal = new AtomicReference(null); 26 | final AtomicReference oldVal = new AtomicReference(null); 27 | final AtomicInteger counter = new AtomicInteger(0); 28 | 29 | Bind.MapListener listener = new Bind.MapListener(){ 30 | @Override public void update(Object key2, Object oldVal2, Object newVal2) { 31 | counter.incrementAndGet(); 32 | key.set(key2); 33 | oldVal.set(oldVal2); 34 | newVal.set(newVal2); 35 | } 36 | }; 37 | 38 | m.modificationListenerAdd(listener); 39 | 40 | //check CRUD 41 | m.put("aa","bb"); 42 | assertTrue(key.get()=="aa" && newVal.get()=="bb" && oldVal.get()==null && counter.get()==1); 43 | 44 | m.put("aa","cc"); 45 | assertTrue(key.get()=="aa" && newVal.get()=="cc" && oldVal.get()=="bb" && counter.get()==2); 46 | 47 | m.remove("aa"); 48 | assertTrue(key.get()=="aa" && newVal.get()==null && oldVal.get()=="cc" && counter.get()==3); 49 | 50 | //check clear() 51 | m.put("aa","bb"); 52 | assertTrue(key.get()=="aa" && newVal.get()=="bb" && oldVal.get()==null && counter.get()==4); 53 | m.clear(); 54 | assertTrue(key.get()=="aa" && newVal.get()==null && oldVal.get()=="bb" && counter.get()==5); 55 | 56 | 57 | //check it was unregistered 58 | counter.set(0); 59 | m.modificationListenerRemove(listener); 60 | m.put("aa","bb"); 61 | assertEquals(0, counter.get()); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue132Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.util.Iterator; 7 | import java.util.Set; 8 | 9 | public class Issue132Test { 10 | 11 | 12 | static void expectCount(Set set, int count) { 13 | Assert.assertEquals(count, count(set.iterator())); 14 | } 15 | 16 | static int count(final Iterator iterator) { 17 | int counter = 0; 18 | while (iterator.hasNext()) { 19 | iterator.next(); 20 | counter++; 21 | } 22 | return counter; 23 | } 24 | 25 | @Test(timeout=50000) 26 | public void test_full() { 27 | long id= 0; 28 | for(int count = 0; count < 50; count++) { 29 | 30 | 31 | DB db = DBMaker.memoryDB() 32 | .checksumEnable().make(); 33 | 34 | 35 | 36 | Set set = db.hashSet("test"); 37 | db.commit(); 38 | 39 | for (int i = 0; i < count; i++) { 40 | set.add(id++); 41 | db.commit(); 42 | } 43 | expectCount(set, count); 44 | 45 | for (int i = 0; i < count; i++) { 46 | set.add(id++); 47 | db.rollback(); 48 | } 49 | expectCount(set, count); 50 | 51 | for (int i = 0; i < count; i++) { 52 | set.add(id++); 53 | } 54 | expectCount(set, count * 2); 55 | db.commit(); 56 | expectCount(set, count * 2); 57 | 58 | db.close(); 59 | 60 | } 61 | } 62 | 63 | @Test(timeout=10000) 64 | public void test_isolate() { 65 | long id= 0; 66 | int count = 18; 67 | 68 | 69 | DB db = DBMaker.memoryDB() 70 | .checksumEnable().make(); 71 | 72 | 73 | Set set = db.hashSet("test"); 74 | db.commit(); 75 | 76 | for (int i = 0; i < count; i++) { 77 | set.add(id++); 78 | } 79 | db.commit(); 80 | expectCount(set, count); 81 | 82 | for (int i = 0; i < count; i++) { 83 | set.add(id++); 84 | } 85 | db.rollback(); 86 | expectCount(set, count); 87 | 88 | for (int i = 0; i < count; i++) { 89 | set.add(id++); 90 | } 91 | expectCount(set, count * 2); 92 | db.commit(); 93 | expectCount(set, count * 2); 94 | 95 | db.close(); 96 | 97 | } 98 | 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue353Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | import static org.junit.Assert.fail; 6 | 7 | import java.util.Random; 8 | import java.util.concurrent.ConcurrentMap; 9 | 10 | import org.junit.After; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | import org.mapdb.DB.HTreeMapMaker; 14 | 15 | public class Issue353Test { 16 | 17 | private ConcurrentMap map; 18 | private DB db; 19 | private Random random = new Random(); 20 | private static final int ITERATIONS = 40000; 21 | 22 | @Before 23 | public void setupDb() { 24 | db = DBMaker.fileDB(UtilsTest.tempDbFile()).closeOnJvmShutdown().mmapFileEnableIfSupported() 25 | .commitFileSyncDisable().transactionDisable().compressionEnable().freeSpaceReclaimQ(0).make(); 26 | HTreeMapMaker maker = db.hashMapCreate("products") 27 | .valueSerializer(Serializer.BYTE_ARRAY) 28 | .keySerializer(Serializer.BYTE_ARRAY) 29 | .counterEnable(); 30 | map = maker.makeOrGet(); 31 | } 32 | 33 | @After 34 | public void shutdownDb() { 35 | db.close(); 36 | } 37 | 38 | @Test 39 | public void iterateKeySet() { 40 | db.commit(); 41 | map.clear(); 42 | db.commit(); 43 | for (int i = 0; i < ITERATIONS; i++) { 44 | map.put(createByteArrayForKey(), createByteArrayForValue()); 45 | } 46 | for (byte[] e : map.keySet()) { 47 | assertNotNull(map.get(e)); 48 | } 49 | assertEquals(ITERATIONS, map.size()); 50 | map.clear(); 51 | db.commit(); 52 | assertEquals(0, map.size()); 53 | for (byte[] e : map.keySet()) { 54 | fail(); 55 | } 56 | map.put(createByteArrayForKey(), createByteArrayForValue()); 57 | db.commit(); 58 | assertEquals(1, map.size()); 59 | boolean found = false; 60 | for (byte[] e : map.keySet()) { 61 | if (found == true) { 62 | fail(); 63 | } 64 | found = true; 65 | } 66 | } 67 | 68 | private byte[] createByteArrayForKey() { 69 | byte[] result = new byte[12]; 70 | random.nextBytes(result); 71 | return result; 72 | } 73 | 74 | private byte[] createByteArrayForValue() { 75 | int size = random.nextInt(300) + 200; 76 | byte[] result = new byte[size]; 77 | random.nextBytes(result); 78 | return result; 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/BTreeMapTest2.java: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2010 Cees De Groot, Alex Boisvert, 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; 18 | 19 | import java.util.concurrent.ConcurrentMap; 20 | 21 | public class BTreeMapTest2 extends ConcurrentMapInterfaceTest { 22 | 23 | protected boolean valsOutside = false; 24 | 25 | public static class Outside extends BTreeMapTest2{ 26 | { 27 | valsOutside = true; 28 | } 29 | } 30 | 31 | public BTreeMapTest2() { 32 | super(false, false, true, true, true, true, false); 33 | } 34 | 35 | StoreDirect r; 36 | 37 | 38 | @Override 39 | protected void setUp() throws Exception { 40 | r = new StoreDirect(null); 41 | r.init(); 42 | } 43 | 44 | @Override 45 | protected void tearDown() throws Exception { 46 | r.close(); 47 | } 48 | 49 | @Override 50 | protected Integer getKeyNotInPopulatedMap() throws UnsupportedOperationException { 51 | return -100; 52 | } 53 | 54 | @Override 55 | protected String getValueNotInPopulatedMap() throws UnsupportedOperationException { 56 | return "XYZ"; 57 | } 58 | 59 | @Override 60 | protected String getSecondValueNotInPopulatedMap() throws UnsupportedOperationException { 61 | return "AAAA"; 62 | } 63 | 64 | @Override 65 | protected ConcurrentMap makeEmptyMap() throws UnsupportedOperationException { 66 | 67 | return new BTreeMap(r,false, 68 | BTreeMap.createRootRef(r,BTreeKeySerializer.INTEGER, Serializer.STRING, 0), 69 | 6,valsOutside,0, BTreeKeySerializer.INTEGER,Serializer.STRING, 70 | 0); 71 | } 72 | 73 | @Override 74 | protected ConcurrentMap makePopulatedMap() throws UnsupportedOperationException { 75 | ConcurrentMap map = makeEmptyMap(); 76 | for (int i = 0; i < 100; i++){ 77 | map.put(i, "aa" + i); 78 | } 79 | return map; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue400Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.File; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class Issue400Test { 11 | 12 | @Test 13 | public void expire_maxSize_with_TTL() throws InterruptedException { 14 | File f = UtilsTest.tempDbFile(); 15 | for (int o = 0; o < 2; o++) { 16 | final DB db = DBMaker.fileDB(f).transactionDisable().make(); 17 | final HTreeMap map = db.hashMapCreate("foo") 18 | .expireMaxSize(1000).expireAfterWrite(1, TimeUnit.DAYS) 19 | .makeOrGet(); 20 | 21 | map.put("foo", "bar"); 22 | 23 | assertEquals("bar", map.get("foo")); 24 | 25 | Thread.sleep(1100); 26 | assertEquals("bar", map.get("foo")); 27 | 28 | db.commit(); 29 | db.close(); 30 | Thread.sleep(1100); 31 | } 32 | } 33 | 34 | @Test(timeout = 200000) 35 | public void expire_maxSize_with_TTL_short() throws InterruptedException { 36 | File f = UtilsTest.tempDbFile(); 37 | for (int o = 0; o < 2; o++) { 38 | final DB db = DBMaker.fileDB(f).transactionDisable().make(); 39 | final HTreeMap map = db.hashMapCreate("foo") 40 | .expireMaxSize(1000).expireAfterWrite(3, TimeUnit.SECONDS) 41 | .makeOrGet(); 42 | 43 | map.put("foo", "bar"); 44 | 45 | assertEquals("bar", map.get("foo")); 46 | 47 | while(map.get("foo")!=null){ 48 | map.get("aa"); //so internal tasks have change to run 49 | Thread.sleep(100); 50 | } 51 | 52 | db.commit(); 53 | db.close(); 54 | Thread.sleep(1100); 55 | } 56 | } 57 | 58 | @Test(timeout = 600000) 59 | public void expire_maxSize_with_TTL_get() throws InterruptedException { 60 | File f = UtilsTest.tempDbFile(); 61 | for (int o = 0; o < 2; o++) { 62 | final DB db = DBMaker.fileDB(f).transactionDisable().make(); 63 | final HTreeMap map = db.hashMapCreate("foo") 64 | .expireMaxSize(1000).expireAfterAccess(3, TimeUnit.SECONDS) 65 | .makeOrGet(); 66 | 67 | map.put("foo", "bar"); 68 | 69 | for(int i=0;i<10;i++) 70 | assertEquals("bar", map.get("foo")); 71 | 72 | Thread.sleep(6000); 73 | map.get("aa"); //so internal tasks have change to run 74 | assertEquals(null, map.get("foo")); 75 | 76 | db.commit(); 77 | db.close(); 78 | Thread.sleep(1100); 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue249Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.Serializable; 6 | import java.util.Map; 7 | 8 | 9 | public class Issue249Test { 10 | 11 | @Test 12 | public void main() { 13 | TxMaker txMaker = DBMaker.memoryDB().closeOnJvmShutdown() 14 | .makeTxMaker(); 15 | DB db = txMaker.makeTx(); 16 | 17 | UploadInfo x = new UploadInfo(); 18 | x.setId(1L); 19 | x.setTitle("nameXXX"); 20 | 21 | Map map = db.treeMap(UploadInfo.class.getName()); 22 | map.put(x.getId(), x); 23 | 24 | db = commit(db); 25 | db = rollback(db); 26 | 27 | DB db2 = txMaker.makeTx(); 28 | Map map2 = db2.treeMap(UploadInfo.class.getName()); 29 | map2.get(x.getId()); 30 | 31 | txMaker.close(); 32 | } 33 | 34 | private static DB commit(DB db) { 35 | if (db != null && !db.isClosed()) 36 | db.commit(); 37 | // db = null; 38 | return db; 39 | } 40 | 41 | private static DB rollback(DB db) { 42 | if (db != null && !db.isClosed()) { 43 | try { 44 | db.rollback(); 45 | } catch (Exception e) { 46 | } 47 | } 48 | // db = null; 49 | return db; 50 | } 51 | 52 | @SuppressWarnings("serial") 53 | public static class UploadInfo implements Serializable { 54 | 55 | private Long id; 56 | private String slug; 57 | private String zipCode; 58 | private String www; 59 | private String text; 60 | private String title; 61 | 62 | public Long getId() { 63 | return id; 64 | } 65 | 66 | public void setId(Long id) { 67 | this.id = id; 68 | } 69 | 70 | public String getSlug() { 71 | return slug; 72 | } 73 | 74 | public void setSlug(String slug) { 75 | this.slug = slug; 76 | } 77 | 78 | public String getZipCode() { 79 | return zipCode; 80 | } 81 | 82 | public void setZipCode(String zipCode) { 83 | this.zipCode = zipCode; 84 | } 85 | 86 | public String getWww() { 87 | return www; 88 | } 89 | 90 | public void setWww(String www) { 91 | this.www = www; 92 | } 93 | 94 | public String getText() { 95 | return text; 96 | } 97 | 98 | public void setText(String text) { 99 | this.text = text; 100 | } 101 | 102 | public String getTitle() { 103 | return title; 104 | } 105 | 106 | public void setTitle(String title) { 107 | this.title = title; 108 | } 109 | 110 | } 111 | 112 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/BTreeMapLargeValsTest.java: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2010 Cees De Groot, Alex Boisvert, 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; 18 | 19 | import org.junit.After; 20 | 21 | import java.util.concurrent.ConcurrentMap; 22 | 23 | public class BTreeMapLargeValsTest extends ConcurrentMapInterfaceTest { 24 | 25 | final String aa = "aiopjdqwoidjiweqpofjoiaergopieraiopgjajeiorgjoiaergiojareiogopij32-p909-iarvp9iaervijoksarfe"; 26 | 27 | public BTreeMapLargeValsTest() { 28 | super(false, false, true, true, true, true,false); 29 | } 30 | 31 | StoreDirect r; 32 | 33 | @Override 34 | protected void setUp() throws Exception { 35 | r = new StoreDirect(null); 36 | r.init(); 37 | } 38 | 39 | 40 | @After 41 | public void close(){ 42 | r.close(); 43 | } 44 | 45 | @Override 46 | protected Integer getKeyNotInPopulatedMap() throws UnsupportedOperationException { 47 | return -100; 48 | } 49 | 50 | @Override 51 | protected String getValueNotInPopulatedMap() throws UnsupportedOperationException { 52 | return aa+"XYZ"; 53 | } 54 | 55 | @Override 56 | protected String getSecondValueNotInPopulatedMap() throws UnsupportedOperationException { 57 | return aa+"AAAA"; 58 | } 59 | 60 | 61 | boolean valsOutside = false; 62 | @Override 63 | protected ConcurrentMap makeEmptyMap() throws UnsupportedOperationException { 64 | return new BTreeMap(r,false, 65 | BTreeMap.createRootRef(r,BTreeKeySerializer.INTEGER, Serializer.STRING,0), 66 | 6,valsOutside,0, BTreeKeySerializer.INTEGER,Serializer.STRING, 67 | 0); 68 | 69 | } 70 | 71 | public static class Outside extends BTreeMapLargeValsTest { 72 | { 73 | valsOutside = true; 74 | } 75 | } 76 | 77 | @Override 78 | protected ConcurrentMap makePopulatedMap() throws UnsupportedOperationException { 79 | ConcurrentMap map = makeEmptyMap(); 80 | for (int i = 0; i < 100; i++){ 81 | map.put(i, aa+"aa" + i); 82 | } 83 | return map; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/HTreeMap3Test.java: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2010 Cees De Groot, Alex Boisvert, 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; 17 | 18 | import org.junit.After; 19 | 20 | import java.util.concurrent.ConcurrentMap; 21 | 22 | public class HTreeMap3Test extends ConcurrentMapInterfaceTest { 23 | 24 | public static class Segmented extends HTreeMap3Test{ 25 | @Override 26 | protected ConcurrentMap makeEmptyMap() throws UnsupportedOperationException { 27 | return DBMaker 28 | .hashMapSegmentedMemory() 29 | .keySerializer(Serializer.INTEGER) 30 | .valueSerializer(Serializer.STRING) 31 | .make(); 32 | } 33 | } 34 | 35 | public HTreeMap3Test() { 36 | super(false, false, true, true, true, true,true); 37 | } 38 | 39 | StoreDirect r; 40 | 41 | @Override 42 | protected void setUp() throws Exception { 43 | r = new StoreDirect(null); 44 | r.init(); 45 | } 46 | 47 | 48 | @Override 49 | protected void tearDown() throws Exception { 50 | r.close(); 51 | } 52 | 53 | @Override 54 | protected Integer getKeyNotInPopulatedMap() throws UnsupportedOperationException { 55 | return -100; 56 | } 57 | 58 | @Override 59 | protected String getValueNotInPopulatedMap() throws UnsupportedOperationException { 60 | return "XYZ"; 61 | } 62 | 63 | @Override 64 | protected String getSecondValueNotInPopulatedMap() throws UnsupportedOperationException { 65 | return "AAAA"; 66 | } 67 | 68 | @Override 69 | protected ConcurrentMap makeEmptyMap() throws UnsupportedOperationException { 70 | Engine[] engines = HTreeMap.fillEngineArray(r); 71 | return new HTreeMap(engines, 72 | false, 0,0, HTreeMap.preallocateSegments(engines), Serializer.BASIC, Serializer.BASIC,0,0,0,0,0,null,null,null,null, 0L,false,null); 73 | } 74 | 75 | @Override 76 | protected ConcurrentMap makePopulatedMap() throws UnsupportedOperationException { 77 | ConcurrentMap map = makeEmptyMap(); 78 | for (int i = 0; i < 100; i++) 79 | map.put(i, "aa" + i); 80 | return map; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/StoreCachedTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.ScheduledExecutorService; 9 | import java.util.concurrent.locks.LockSupport; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | @SuppressWarnings({"rawtypes","unchecked"}) 14 | public class StoreCachedTest extends StoreDirectTest{ 15 | 16 | @Override boolean canRollback(){return false;} 17 | 18 | File f = UtilsTest.tempDbFile(); 19 | 20 | 21 | @Override protected E openEngine() { 22 | StoreCached e =new StoreCached(f.getPath()); 23 | e.init(); 24 | return (E)e; 25 | } 26 | 27 | @Test public void put_delete(){ 28 | long recid = e.put(1L, Serializer.LONG); 29 | int pos = e.lockPos(recid); 30 | assertEquals(1, e.writeCache[pos].size); 31 | e.delete(recid,Serializer.LONG); 32 | assertEquals(1, e.writeCache[pos].size); 33 | } 34 | 35 | @Test public void put_update_delete(){ 36 | long recid = e.put(1L, Serializer.LONG); 37 | int pos = e.lockPos(recid); 38 | assertEquals(1, e.writeCache[pos].size); 39 | e.update(2L, recid,Serializer.LONG); 40 | assertEquals(1,e.writeCache[pos].size); 41 | e.delete(recid,Serializer.LONG); 42 | assertEquals(1,e.writeCache[pos].size); 43 | } 44 | 45 | @Test(timeout = 100000) 46 | public void flush_write_cache(){ 47 | 48 | for(ScheduledExecutorService E: 49 | new ScheduledExecutorService[]{ 50 | null, 51 | Executors.newSingleThreadScheduledExecutor() 52 | }) { 53 | final int M = 1234; 54 | StoreCached s = new StoreCached( 55 | null, 56 | Volume.memoryFactory(), 57 | null, 58 | 1, 59 | 0, 60 | false, 61 | false, 62 | null, 63 | false, 64 | 0, 65 | false, 66 | 0, 67 | E, 68 | 1024, 69 | M 70 | ); 71 | s.init(); 72 | 73 | assertEquals(M, s.writeQueueSize); 74 | assertEquals(0, s.writeCache[0].size); 75 | 76 | //write some stuff so cache is almost full 77 | for (int i = 0; i < M ; i++) { 78 | s.put("aa", Serializer.STRING); 79 | } 80 | 81 | assertEquals(M, s.writeCache[0].size); 82 | 83 | //one extra item causes overflow 84 | s.put("bb",Serializer.STRING); 85 | 86 | 87 | while(E!=null && s.writeCache[0].size>0){ 88 | LockSupport.parkNanos(1000); 89 | } 90 | 91 | assertEquals(0, s.writeCache[0].size); 92 | 93 | if(E!=null) 94 | E.shutdown(); 95 | } 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Serialization2Bean.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import java.io.Serializable; 4 | 5 | 6 | public class Serialization2Bean implements Serializable { 7 | // =========================== Constants =============================== 8 | private static final long serialVersionUID = 2757814409580877461L; 9 | 10 | // =========================== Attributes ============================== 11 | private String id = "test"; 12 | private String f1 = ""; 13 | private String f2 = ""; 14 | private String f3 = null; 15 | private String f4 = ""; 16 | private String f5 = null; 17 | private String f6 = ""; 18 | 19 | @Override 20 | public int hashCode() { 21 | final int prime = 31; 22 | int result = 1; 23 | result = prime * result + ((f1 == null) ? 0 : f1.hashCode()); 24 | result = prime * result + ((f2 == null) ? 0 : f2.hashCode()); 25 | result = prime * result + ((f3 == null) ? 0 : f3.hashCode()); 26 | result = prime * result + ((f4 == null) ? 0 : f4.hashCode()); 27 | result = prime * result + ((f5 == null) ? 0 : f5.hashCode()); 28 | result = prime * result + ((f6 == null) ? 0 : f6.hashCode()); 29 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 30 | return result; 31 | } 32 | 33 | @Override 34 | public boolean equals(Object obj) { 35 | if (this == obj) { 36 | return true; 37 | } 38 | if (obj == null) { 39 | return false; 40 | } 41 | if (getClass() != obj.getClass()) { 42 | return false; 43 | } 44 | Serialization2Bean other = (Serialization2Bean) obj; 45 | if (f1 == null) { 46 | if (other.f1 != null) { 47 | return false; 48 | } 49 | } else if (!f1.equals(other.f1)) { 50 | return false; 51 | } 52 | if (f2 == null) { 53 | if (other.f2 != null) { 54 | return false; 55 | } 56 | } else if (!f2.equals(other.f2)) { 57 | return false; 58 | } 59 | if (f3 == null) { 60 | if (other.f3 != null) { 61 | return false; 62 | } 63 | } else if (!f3.equals(other.f3)) { 64 | return false; 65 | } 66 | if (f4 == null) { 67 | if (other.f4 != null) { 68 | return false; 69 | } 70 | } else if (!f4.equals(other.f4)) { 71 | return false; 72 | } 73 | if (f5 == null) { 74 | if (other.f5 != null) { 75 | return false; 76 | } 77 | } else if (!f5.equals(other.f5)) { 78 | return false; 79 | } 80 | if (f6 == null) { 81 | if (other.f6 != null) { 82 | return false; 83 | } 84 | } else if (!f6.equals(other.f6)) { 85 | return false; 86 | } 87 | if (id == null) { 88 | if (other.id != null) { 89 | return false; 90 | } 91 | } else if (!id.equals(other.id)) { 92 | return false; 93 | } 94 | return true; 95 | } 96 | 97 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue154Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.util.Map; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class Issue154Test { 11 | 12 | @Test 13 | public void HTreeMap(){ 14 | TxMaker txMaker = DBMaker.memoryDB().makeTxMaker(); 15 | 16 | /* Add the item */ 17 | 18 | DB db1 = txMaker.makeTx(); 19 | Map map1 = db1.hashMap("simple"); 20 | map1.put("a", "b"); 21 | db1.commit(); 22 | 23 | /* Remove the item */ 24 | 25 | DB db2 = txMaker.makeTx(); 26 | Map map2 = db2.hashMap("simple"); 27 | 28 | // Make sure the item is still there 29 | assertEquals("b",map2.get("a")); 30 | map2.remove("a"); 31 | assertEquals(null,map2.get("a")); 32 | // ROLLBACK the removal (in theory) 33 | db2.rollback(); 34 | 35 | /* Check for the rolled back item */ 36 | 37 | DB db3 = txMaker.makeTx(); 38 | Map map3 = db3.hashMap("simple"); 39 | 40 | // *************** 41 | // THIS IS WHERE IT FAILS, but the object should be the same, since it the remove was rolled back 42 | // *************** 43 | 44 | assertEquals("b",map3.get("a")); 45 | 46 | db3.close(); 47 | } 48 | 49 | @Test public void simple(){ 50 | TxMaker txMaker = DBMaker.memoryDB().makeTxMaker(); 51 | Engine engine = txMaker.makeTx().getEngine(); 52 | long recid = engine.put("aa",Serializer.STRING_NOSIZE); 53 | engine.commit(); 54 | engine = txMaker.makeTx().getEngine(); 55 | assertEquals("aa",engine.get(recid,Serializer.STRING_NOSIZE)); 56 | engine.delete(recid,Serializer.STRING_NOSIZE); 57 | assertEquals(null,engine.get(recid,Serializer.STRING_NOSIZE)); 58 | engine.rollback(); 59 | engine = txMaker.makeTx().getEngine(); 60 | assertEquals("aa",engine.get(recid,Serializer.STRING_NOSIZE)); 61 | 62 | } 63 | 64 | @Test 65 | public void BTreeMap(){ 66 | TxMaker txMaker = DBMaker.memoryDB().makeTxMaker(); 67 | 68 | /* Add the item */ 69 | 70 | DB db1 = txMaker.makeTx(); 71 | Map map1 = db1.treeMap("simple"); 72 | map1.put("a", "b"); 73 | db1.commit(); 74 | 75 | /* Remove the item */ 76 | 77 | DB db2 = txMaker.makeTx(); 78 | Map map2 = db2.treeMap("simple"); 79 | 80 | // Make sure the item is still there 81 | assertEquals("b",map2.get("a")); 82 | map2.remove("a"); 83 | assertEquals(null,map2.get("a")); 84 | // ROLLBACK the removal (in theory) 85 | db2.rollback(); 86 | 87 | /* Check for the rolled back item */ 88 | 89 | DB db3 = txMaker.makeTx(); 90 | Map map3 = db3.treeMap("simple"); 91 | 92 | // *************** 93 | // THIS IS WHERE IT FAILS, but the object should be the same, since it the remove was rolled back 94 | // *************** 95 | 96 | assertEquals("b",map3.get("a")); 97 | 98 | db3.close(); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/SerializerTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.IOException; 6 | import java.util.Arrays; 7 | import java.util.Random; 8 | import java.util.UUID; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | @SuppressWarnings({"rawtypes","unchecked"}) 13 | public class SerializerTest { 14 | 15 | @Test public void UUID2(){ 16 | UUID u = UUID.randomUUID(); 17 | assertEquals(u, SerializerBaseTest.clone2(u,Serializer.UUID)); 18 | } 19 | 20 | @Test public void string_ascii(){ 21 | String s = "adas9 asd9009asd"; 22 | assertEquals(s,SerializerBaseTest.clone2(s,Serializer.STRING_ASCII)); 23 | s = ""; 24 | assertEquals(s, SerializerBaseTest.clone2(s,Serializer.STRING_ASCII)); 25 | s = " "; 26 | assertEquals(s, SerializerBaseTest.clone2(s,Serializer.STRING_ASCII)); 27 | } 28 | 29 | @Test public void compression_wrapper() throws IOException { 30 | byte[] b = new byte[100]; 31 | new Random().nextBytes(b); 32 | Serializer ser = new Serializer.CompressionWrapper(Serializer.BYTE_ARRAY); 33 | assertTrue(Serializer.BYTE_ARRAY.equals(b, SerializerBaseTest.clone2(b, ser))); 34 | 35 | b = Arrays.copyOf(b, 10000); 36 | assertTrue(Serializer.BYTE_ARRAY.equals(b, SerializerBaseTest.clone2(b, ser))); 37 | 38 | DataIO.DataOutputByteArray out = new DataIO.DataOutputByteArray(); 39 | ser.serialize(out,b); 40 | assertTrue(out.pos < 1000); 41 | } 42 | 43 | @Test public void array(){ 44 | Serializer.Array s = new Serializer.Array(Serializer.INTEGER); 45 | 46 | Object[] a = new Object[]{1,2,3,4}; 47 | 48 | assertArrayEquals(a, UtilsTest.clone(a, s)); 49 | assertEquals(s, UtilsTest.clone(s, Serializer.BASIC)); 50 | } 51 | 52 | void testLong(Serializer ser){ 53 | for(Long i= (long) -1e5;i<1e5;i++){ 54 | assertEquals(i, UtilsTest.clone(i,ser)); 55 | } 56 | 57 | for(Long i=0L;i>0;i+=1+i/10000){ 58 | assertEquals(i, UtilsTest.clone(i, ser)); 59 | assertEquals(new Long(-i), UtilsTest.clone(-i, ser)); 60 | } 61 | } 62 | 63 | @Test public void Long(){ 64 | testLong(Serializer.LONG); 65 | } 66 | 67 | 68 | @Test public void Long_packed(){ 69 | testLong(Serializer.LONG_PACKED); 70 | } 71 | 72 | @Test public void Long_packed_zigzag(){ 73 | testLong(Serializer.LONG_PACKED_ZIGZAG); 74 | } 75 | 76 | 77 | void testInt(Serializer ser){ 78 | for(Integer i= (int) -1e5;i<1e5;i++){ 79 | assertEquals(i, UtilsTest.clone(i,ser)); 80 | } 81 | 82 | for(Integer i=0;i>0;i+=1+i/10000){ 83 | assertEquals(i, UtilsTest.clone(i, ser)); 84 | assertEquals(new Long(-i), UtilsTest.clone(-i, ser)); 85 | } 86 | } 87 | 88 | @Test public void Int(){ 89 | testInt(Serializer.INTEGER); 90 | } 91 | 92 | 93 | @Test public void Int_packed(){ 94 | testInt(Serializer.INTEGER_PACKED); 95 | } 96 | 97 | @Test public void Int_packed_zigzag(){ 98 | testInt(Serializer.INTEGER_PACKED_ZIGZAG); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Serialization2Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.io.Serializable; 9 | import java.util.Map; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | import static org.junit.Assert.assertNotNull; 13 | 14 | public class Serialization2Test{ 15 | 16 | 17 | @Test public void test2() throws IOException { 18 | File index = UtilsTest.tempDbFile(); 19 | DB db = DBMaker.fileDB(index).transactionDisable().make(); 20 | 21 | Serialization2Bean processView = new Serialization2Bean(); 22 | 23 | Map map = db.hashMap("test2"); 24 | 25 | map.put("abc", processView); 26 | 27 | db.commit(); 28 | 29 | Serialization2Bean retProcessView = (Serialization2Bean)map.get("abc"); 30 | assertEquals(processView, retProcessView); 31 | 32 | db.close(); 33 | } 34 | 35 | 36 | @Test public void test2_engine() throws IOException { 37 | File index = UtilsTest.tempDbFile(); 38 | DB db = DBMaker.fileDB(index).make(); 39 | 40 | Serialization2Bean processView = new Serialization2Bean(); 41 | 42 | long recid = db.engine.put(processView, (Serializer) db.getDefaultSerializer()); 43 | 44 | db.commit(); 45 | 46 | Serialization2Bean retProcessView = (Serialization2Bean) db.engine.get(recid, db.getDefaultSerializer()); 47 | assertEquals(processView, retProcessView); 48 | 49 | db.close(); 50 | } 51 | 52 | 53 | @Test public void test3() throws IOException { 54 | File index = UtilsTest.tempDbFile(); 55 | 56 | Serialized2DerivedBean att = new Serialized2DerivedBean(); 57 | DB db = DBMaker.fileDB(index).make(); 58 | 59 | Map map = db.hashMap("test"); 60 | 61 | map.put("att", att); 62 | db.commit(); 63 | db.close(); 64 | db = DBMaker.fileDB(index).make(); 65 | map = db.hashMap("test"); 66 | 67 | 68 | Serialized2DerivedBean retAtt = (Serialized2DerivedBean) map.get("att"); 69 | assertEquals(att, retAtt); 70 | } 71 | 72 | 73 | 74 | static class AAA implements Serializable { 75 | 76 | private static final long serialVersionUID = 632633199013551846L; 77 | 78 | String test = "aa"; 79 | } 80 | 81 | 82 | @Test public void testReopenWithDefrag(){ 83 | 84 | File f = UtilsTest.tempDbFile(); 85 | 86 | DB db = DBMaker.fileDB(f) 87 | .transactionDisable() 88 | .checksumEnable() 89 | .make(); 90 | 91 | Map map = db.treeMap("test"); 92 | map.put(1,new AAA()); 93 | 94 | db.compact(); 95 | System.out.println(db.getEngine().get(Engine.RECID_CLASS_CATALOG, SerializerPojo.CLASS_CATALOG_SERIALIZER)); 96 | db.close(); 97 | 98 | db = DBMaker.fileDB(f) 99 | .transactionDisable() 100 | .checksumEnable() 101 | .make(); 102 | 103 | map = db.treeMap("test"); 104 | assertNotNull(map.get(1)); 105 | assertEquals(map.get(1).test, "aa"); 106 | 107 | 108 | db.close(); 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/AtomicBooleanTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb;/* 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 | 9 | import junit.framework.TestCase; 10 | 11 | public class AtomicBooleanTest extends TestCase{ 12 | 13 | DB db; 14 | Atomic.Boolean ai; 15 | 16 | @Override 17 | protected void setUp() throws Exception { 18 | db = DBMaker.memoryDB().transactionDisable().make(); 19 | ai= db.atomicBooleanCreate("test", true);; 20 | } 21 | 22 | @Override 23 | protected void tearDown() throws Exception { 24 | db.close(); 25 | } 26 | 27 | 28 | /* 29 | * constructor initializes to given value 30 | */ 31 | public void testConstructor() { 32 | assertEquals(true,ai.get()); 33 | } 34 | 35 | /* 36 | * default constructed initializes to false 37 | */ 38 | public void testConstructor2() { 39 | Atomic.Boolean ai = db.atomicBoolean("test2"); 40 | assertEquals(false,ai.get()); 41 | } 42 | 43 | /* 44 | * get returns the last value set 45 | */ 46 | public void testGetSet() { 47 | 48 | assertEquals(true,ai.get()); 49 | ai.set(false); 50 | assertEquals(false,ai.get()); 51 | ai.set(true); 52 | assertEquals(true,ai.get()); 53 | 54 | } 55 | 56 | /* 57 | * compareAndSet succeeds in changing value if equal to expected else fails 58 | */ 59 | public void testCompareAndSet() { 60 | 61 | assertTrue(ai.compareAndSet(true,false)); 62 | assertEquals(false,ai.get()); 63 | assertTrue(ai.compareAndSet(false,false)); 64 | assertEquals(false,ai.get()); 65 | assertFalse(ai.compareAndSet(true,false)); 66 | assertFalse((ai.get())); 67 | assertTrue(ai.compareAndSet(false,true)); 68 | assertEquals(true,ai.get()); 69 | } 70 | 71 | /* 72 | * compareAndSet in one thread enables another waiting for value 73 | * to succeed 74 | */ 75 | public void testCompareAndSetInMultipleThreads() throws InterruptedException { 76 | Thread t = new Thread(new Runnable() { 77 | public void run() { 78 | while(!ai.compareAndSet(false, true)) Thread.yield(); 79 | }}); 80 | 81 | t.start(); 82 | assertTrue(ai.compareAndSet(true, false)); 83 | t.join(0); 84 | assertFalse(t.isAlive()); 85 | 86 | } 87 | 88 | /* 89 | * getAndSet returns previous value and sets to given value 90 | */ 91 | public void testGetAndSet() { 92 | assertEquals(true,ai.getAndSet(false)); 93 | assertEquals(false,ai.getAndSet(false)); 94 | assertEquals(false,ai.getAndSet(true)); 95 | assertEquals(true,ai.get()); 96 | } 97 | /* 98 | * toString returns current value. 99 | */ 100 | public void testToString() { 101 | Atomic.Boolean ai = db.atomicBoolean("test2"); 102 | assertEquals(ai.toString(), Boolean.toString(false)); 103 | ai.set(true); 104 | assertEquals(ai.toString(), Boolean.toString(true)); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue164Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.Serializable; 6 | import java.util.HashSet; 7 | 8 | import static org.junit.Assert.assertTrue; 9 | 10 | public class Issue164Test { 11 | 12 | public static class Scenario implements Serializable { 13 | private static final long serialVersionUID = 1L; 14 | protected String id = null; 15 | protected String brief = null; 16 | protected String headNodeId = null; 17 | protected HashSet nodeIdSet = null; 18 | public Scenario() { 19 | id = Long.toHexString(System.nanoTime()); 20 | brief = null; 21 | headNodeId = null; 22 | nodeIdSet = null; 23 | } 24 | public void setId(String arg_id) { 25 | synchronized(this) { 26 | id = arg_id; 27 | } 28 | } 29 | public String getId() { 30 | synchronized(this) { 31 | return id; 32 | } 33 | } 34 | public void setBrief(String arg_brief) { 35 | synchronized(this) { 36 | brief = arg_brief; 37 | } 38 | } 39 | public String getBrief() { 40 | synchronized(this) { 41 | return brief; 42 | } 43 | } 44 | public String getHeadNodeId() { 45 | synchronized(this) { 46 | return headNodeId; 47 | } 48 | } 49 | public void setHeadNodeId(String arg_header_node_id) { 50 | synchronized(this) { 51 | headNodeId = arg_header_node_id; 52 | if (!nodeIdSet.contains(arg_header_node_id)) 53 | nodeIdSet.add(arg_header_node_id); 54 | } 55 | } 56 | public void addConversationNodeId(String arg_conversation_node_id) throws Exception { 57 | synchronized(this) { 58 | if (headNodeId == null) { 59 | headNodeId = arg_conversation_node_id; 60 | nodeIdSet.add(arg_conversation_node_id); 61 | } 62 | else 63 | throw new Exception(); 64 | } // of synchronized(this) 65 | } 66 | public void removeConversationNodeId(String arg_conversation_node_id) { 67 | synchronized(this) { 68 | if (headNodeId != null) { 69 | nodeIdSet.remove(arg_conversation_node_id); 70 | if (arg_conversation_node_id.equals(headNodeId)) 71 | headNodeId = null; // the set is empty now 72 | } 73 | } // of synchronized(this) 74 | } 75 | } 76 | 77 | 78 | @Test 79 | public void main() { 80 | int rc = 0; 81 | BTreeMap map=null; 82 | try { 83 | DB db = DBMaker.memoryDB() 84 | .closeOnJvmShutdown() 85 | .make(); 86 | // the following test shows that the db is opened if it always exists 87 | map = db.treeMap("test"); 88 | if (!map.containsKey("t1")) { 89 | map.put("t1", new Scenario()); 90 | db.commit(); 91 | } 92 | rc = 1; 93 | } catch(Exception ex) { 94 | rc = -1; 95 | } 96 | assertTrue(map.get("t1")!=null); 97 | assertTrue(rc > 0); 98 | 99 | } 100 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue150Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | import java.io.Serializable; 10 | import java.util.Map; 11 | 12 | public class Issue150Test { 13 | 14 | @Test 15 | public void test() { 16 | // TxMaker txMaker = DBMaker.fileDB(new File("/tmp/mapdb.test")) 17 | // .closeOnJvmShutdown().asyncWriteDisable().makeTxMaker(); 18 | TxMaker txMaker = DBMaker.memoryDB().closeOnJvmShutdown() 19 | .makeTxMaker(); 20 | 21 | DB db = txMaker.makeTx(); 22 | 23 | EntityA x = new EntityA(); 24 | x.setId(126l); 25 | x.setName("nameXXX"); 26 | 27 | Serializer valueSerializer = new CustomSerializer(); 28 | Map map = db.hashMapCreate("entitya").valueSerializer(valueSerializer).make(); 29 | 30 | map.put(x.getId(), x); 31 | 32 | db.commit(); 33 | 34 | EntityA y = (EntityA) txMaker.makeTx().hashMap("entitya") 35 | .get(x.getId()); 36 | System.out.println(x.equals(y)); 37 | 38 | txMaker.close(); 39 | } 40 | 41 | private static final class CustomSerializer extends 42 | Serializer implements Serializable { 43 | 44 | @Override 45 | public void serialize(DataOutput out, EntityA value) throws IOException { 46 | out.writeLong(value.getId()); 47 | out.writeUTF(value.getName()); 48 | } 49 | 50 | @Override 51 | public EntityA deserialize(DataInput in, int available) 52 | throws IOException { 53 | 54 | EntityA a = new EntityA(); 55 | a.setId(in.readLong()); 56 | a.setName(in.readUTF()); 57 | return a; 58 | } 59 | 60 | } 61 | 62 | public static class EntityA implements Serializable { 63 | 64 | private Long id; 65 | 66 | private String name; 67 | 68 | public Long getId() { 69 | return id; 70 | } 71 | 72 | public void setId(Long id) { 73 | this.id = id; 74 | } 75 | 76 | public String getName() { 77 | return name; 78 | } 79 | 80 | public void setName(String name) { 81 | this.name = name; 82 | } 83 | 84 | @Override 85 | public int hashCode() { 86 | final int prime = 31; 87 | int result = 1; 88 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 89 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 90 | return result; 91 | } 92 | 93 | @Override 94 | public boolean equals(Object obj) { 95 | if (this == obj) 96 | return true; 97 | if (obj == null) 98 | return false; 99 | if (getClass() != obj.getClass()) 100 | return false; 101 | EntityA other = (EntityA) obj; 102 | if (id == null) { 103 | if (other.id != null) 104 | return false; 105 | } else if (!id.equals(other.id)) 106 | return false; 107 | if (name == null) { 108 | if (other.name != null) 109 | return false; 110 | } else if (!name.equals(other.name)) 111 | return false; 112 | return true; 113 | } 114 | 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/test/java/examples/Transactions.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.DB; 4 | import org.mapdb.DBMaker; 5 | import org.mapdb.TxMaker; 6 | import org.mapdb.TxRollbackException; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * MapDB provides concurrent transactions with Serialized Snapshot Isolation to manage MVCC. 12 | * This example shows how to invoke multiple transactions at the same time. 13 | * It also shows rollback in case of an concurrent update conflict 14 | */ 15 | public class Transactions { 16 | public static void main(String[] args) { 17 | 18 | 19 | //Open Transaction Factory. DBMaker shares most options with single-transaction mode. 20 | TxMaker txMaker = DBMaker 21 | .memoryDB() 22 | .makeTxMaker(); 23 | 24 | // Now open first transaction and get map from first transaction 25 | DB tx1 = txMaker.makeTx(); 26 | 27 | //create map from first transactions and fill it with data 28 | Map map1 = tx1.treeMap("testMap"); 29 | for(int i=0;i<1e4;i++){ 30 | map1.put(i,"aaa"+i); 31 | } 32 | 33 | //commit first transaction 34 | tx1.commit(); 35 | 36 | // !! IMPORTANT !! 37 | // !! DB transaction can be used only once, 38 | // !! it throws an 'already closed' exception after it was commited/rolledback 39 | // !! IMPORTANT !! 40 | //map1.put(1111,"dqdqwd"); // this will fail 41 | 42 | //open second transaction 43 | DB tx2 = txMaker.makeTx(); 44 | Map map2 = tx2.treeMap("testMap"); 45 | 46 | //open third transaction 47 | DB tx3 = txMaker.makeTx(); 48 | Map map3 = tx3.treeMap("testMap"); 49 | 50 | //put some stuff into second transactions, observer third map size 51 | System.out.println("map3 size before insert: "+map3.size()); 52 | map2.put(-10, "exists"); 53 | System.out.println("map3 size after insert: "+map3.size()); 54 | 55 | //put some stuff into third transactions, observer second map size 56 | System.out.println("map2 size before insert: "+map2.size()); 57 | map3.put(100000, "exists"); 58 | System.out.println("map2 size after insert: "+map2.size()); 59 | 60 | // so far there was no conflict, since modified Map values lie far away from each other in tree. 61 | // `map2` has new key -10, so inserting -11 into map3 should update the same node 62 | map3.put(-11, "exists"); 63 | // `map2` and `map3` now have conflicting data 64 | tx3.commit(); 65 | System.out.println("Insert -11 into map3 was fine"); 66 | 67 | //tx3 was commited, but tx2 now has conflicting data, so its commit will fail 68 | try{ 69 | tx2.commit(); 70 | throw new Error("Should not be here"); 71 | }catch(TxRollbackException e){ 72 | System.out.println("Tx2 commit failed thanks to conflict, tx2 was rolled back"); 73 | } 74 | 75 | //create yet another transaction and observe result 76 | DB tx4 = txMaker.makeTx(); 77 | Map map4 = tx4.treeMap("testMap"); 78 | System.out.println("Map size after commits: "+map4.size()); 79 | System.out.println("Value inserted into tx2 and successfully commited: "+map4.get(-10)); 80 | System.out.println("Value inserted into tx3 before rollback: "+map4.get(100000)); 81 | System.out.println("Value inserted into tx3 which triggered rollback: "+map4.get(-11)); 82 | 83 | //close transaction without modifying anything 84 | tx4.close(); 85 | 86 | //close the entire database 87 | txMaker.close(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/test/java/examples/TreeMap_Performance_Tunning.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.DB; 4 | import org.mapdb.DBMaker; 5 | 6 | import java.io.File; 7 | import java.util.Map; 8 | import java.util.Random; 9 | 10 | /* 11 | * Demonstrates how BTree parameters affects performance. BTreeMap has two key parameters 12 | * which affects its performance: 13 | *

Maximal node size

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

Store values inside node

20 | * Value may be stored inside or outside of BTree node. 21 | * It is recommended to store large values outside nodes. 22 | * 23 | * 24 | * 25 | * Sample output 26 | *
27 |  *  Node size |  small vals  |  large vals  |  large vals outside node
28 |  *     6      |       25 s   |       89 s   |    49 s   |
29 |  *    18      |       25 s   |      144 s   |    50 s   |
30 |  *    32      |       57 s   |      175 s   |    31 s   |
31 |  *    64      |       53 s   |      231 s   |    49 s   |
32 |  *   120      |       73 s   |       98 s   |    49 s   |
33 |  * 
34 | */ 35 | public class TreeMap_Performance_Tunning { 36 | 37 | 38 | static final int[] nodeSizes = {6, 18, 32, 64, 120}; 39 | 40 | 41 | public static void main(String[] args) { 42 | Random r = new Random(); 43 | 44 | 45 | 46 | System.out.println(" Node size | small vals | large vals | large vals outside node" ); 47 | 48 | for(int nodeSize:nodeSizes){ 49 | 50 | System.out .print(" "+nodeSize+" |"); 51 | 52 | for(int j=0;j<3;j++){ 53 | 54 | boolean useSmallValues = (j==0); 55 | boolean valueOutsideOfNodes = (j==2); 56 | 57 | DB db = DBMaker 58 | .fileDB(new File("/mnt/big/adsasd")) 59 | .deleteFilesAfterClose() 60 | .closeOnJvmShutdown() 61 | .transactionDisable() 62 | .cacheSize(10) //use small cache size, to simulate much larger store with relatively small cache. 63 | .make(); 64 | 65 | 66 | Map map = 67 | (valueOutsideOfNodes? 68 | (db.treeMapCreate("test").valuesOutsideNodesEnable()): 69 | db.treeMapCreate("test")) 70 | .nodeSize(nodeSize) 71 | .make(); 72 | 73 | long startTime = System.currentTimeMillis(); 74 | 75 | for(int i=0;i<1e6;i++){ 76 | long key = r.nextLong(); 77 | String value = useSmallValues? 78 | //small value 79 | "abc"+key: 80 | //large value 81 | "qwdkqwdoqpwfwe-09fewkljklcejewfcklajewjkleawckjlaweklcwelkcwecklwecjwekecklwecklaa" 82 | +"kvlskldvklsdklcklsdvkdflvvvvvvvvvvvvvvvvvvvvvvvsl;kzlkvlksdlkvklsdklvkldsklk" 83 | +key; 84 | map.put(key, value); 85 | } 86 | 87 | System.out.print(" "); 88 | System.out.print((System.currentTimeMillis()-startTime)/1000+" s"); 89 | System.out.print(" |"); 90 | db.close(); 91 | } 92 | System.out.println(""); 93 | } 94 | } 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue162Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.*; 6 | import java.util.Map; 7 | 8 | import static org.junit.Assert.assertTrue; 9 | 10 | 11 | public class Issue162Test { 12 | 13 | public static class MyValue implements Serializable { 14 | private String string; 15 | 16 | public MyValue(String string) { 17 | this.string = string; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "MyValue{" + "string='" + string + '\'' + '}'; 23 | } 24 | 25 | 26 | @Override 27 | public boolean equals(Object o) { 28 | if (this == o) return true; 29 | if (!(o instanceof MyValue)) return false; 30 | 31 | MyValue myValue = (MyValue) o; 32 | if (!string.equals(myValue.string)) return false; 33 | return true; 34 | } 35 | 36 | 37 | @Override 38 | public int hashCode() { 39 | return string.hashCode(); 40 | } 41 | } 42 | 43 | public static class MyValueSerializer extends Serializer implements Serializable { 44 | 45 | @Override 46 | public void serialize(DataOutput out, MyValue value) throws IOException { 47 | assertTrue(value != null); 48 | System.out.println("Custom serializer called with '" + value + "'"); 49 | out.writeUTF(value.string); 50 | } 51 | 52 | @Override 53 | public MyValue deserialize(DataInput in, int available) throws IOException { 54 | String s = in.readUTF(); 55 | return new MyValue(s); 56 | } 57 | 58 | } 59 | 60 | private static void printEntries(Map map) { 61 | System.out.println("Reading back data"); 62 | for (Map.Entry entry : map.entrySet()) { 63 | System.out.println("Entry id = " + entry.getKey() + ", contents = " + entry.getValue().toString()); 64 | } 65 | } 66 | 67 | File path = UtilsTest.tempDbFile(); 68 | 69 | @Test public void testHashMap() { 70 | System.out.println("--- Testing HashMap with custom serializer"); 71 | 72 | DB db = DBMaker.fileDB(path).make(); 73 | Map map = db.hashMapCreate("map") 74 | .valueSerializer(new MyValueSerializer()) 75 | .make(); 76 | db.commit(); 77 | 78 | System.out.println("Putting and committing data"); 79 | map.put(1L, new MyValue("one")); 80 | map.put(2L, new MyValue("two")); 81 | db.commit(); 82 | 83 | System.out.println("Closing and reopening db"); 84 | db.close(); 85 | map = null; 86 | 87 | db = DBMaker.fileDB(path).make(); 88 | map = db.hashMap("map"); 89 | 90 | printEntries(map); 91 | } 92 | 93 | @Test public void testBTreeMap() { 94 | System.out.println("--- Testing BTreeMap with custom serializer"); 95 | 96 | DB db = DBMaker.fileDB(path).make(); 97 | Map map = db.treeMapCreate("map") 98 | .valueSerializer(new MyValueSerializer()) 99 | .make(); 100 | db.commit(); 101 | 102 | System.out.println("Putting and committing data"); 103 | map.put(1L, new MyValue("one")); 104 | map.put(2L, new MyValue("two")); 105 | db.commit(); 106 | 107 | System.out.println("Closing and reopening db"); 108 | db.close(); 109 | map = null; 110 | 111 | db = DBMaker.fileDB(path).make(); 112 | map = db.treeMap("map"); 113 | 114 | printEntries(map); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/PumpComparableValueTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import java.util.Iterator; 5 | 6 | import org.junit.Test; 7 | import org.mapdb.Fun.Pair; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | 12 | public class PumpComparableValueTest { 13 | 14 | 15 | /* 16 | * Test mapDB data pump mechanize 17 | * 18 | */ 19 | @Test 20 | public void run(){ 21 | DB mapDBStore = DBMaker.memoryDB() 22 | .transactionDisable() 23 | .make(); 24 | 25 | final int max = 70000; 26 | 27 | final int pumpSize = max/10; 28 | 29 | // data source returning the same value max times values are NOT comparable 30 | Iterator> entriesSourceNonComp = new Iterator>() { 31 | int count = 0; 32 | @Override 33 | public void remove() {throw new IllegalArgumentException("NOT SUPPORTED");} 34 | 35 | @Override 36 | public Pair next() { 37 | count++; 38 | 39 | String key ="SAME KEY"; 40 | byte []value = {1}; 41 | 42 | Pair ret = new Pair(key,value); 43 | return ret; 44 | } 45 | 46 | @Override 47 | public boolean hasNext() { 48 | return count map2 = mapDBStore.treeMapCreate("non comparable values") 55 | .pumpSource(entriesSourceNonComp) 56 | .pumpPresort(pumpSize) 57 | .pumpIgnoreDuplicates() 58 | .counterEnable() 59 | .makeStringMap(); 60 | 61 | assertEquals(1,map2.size()); 62 | 63 | } 64 | 65 | @Test 66 | public void run2(){ 67 | DB db = DBMaker.memoryDB() 68 | .transactionDisable().make(); 69 | 70 | 71 | final int max = 70000; 72 | 73 | final int pumpSize = max/10; 74 | 75 | // data source returning the same value max times values are NOT comparable 76 | Iterator> entriesSourceNonComp = new Iterator>() { 77 | int count = 0; 78 | @Override 79 | public void remove() {throw new IllegalArgumentException("NOT SUPPORTED");} 80 | 81 | @Override 82 | public Pair next() { 83 | count++; 84 | 85 | String key = ""+count; 86 | byte []value = {1}; 87 | 88 | Pair ret = new Pair(key,value); 89 | return ret; 90 | } 91 | 92 | @Override 93 | public boolean hasNext() { 94 | return count map2 = db.treeMapCreate("non comparable values") 101 | .pumpSource(entriesSourceNonComp) 102 | .pumpPresort(pumpSize) 103 | .pumpIgnoreDuplicates() 104 | .counterEnable() 105 | .makeStringMap(); 106 | 107 | assertEquals(max,map2.size()); 108 | 109 | 110 | } 111 | 112 | 113 | } -------------------------------------------------------------------------------- /src/main/java/org/mapdb/DBException.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import java.io.IOException; 4 | import java.nio.channels.ClosedByInterruptException; 5 | 6 | /** 7 | * General exception returned by MapDB if something goes wrong. 8 | * Subclasses inform about specific failure. 9 | * 10 | */ 11 | public class DBException extends RuntimeException{ 12 | 13 | 14 | public DBException(String message) { 15 | super(message); 16 | } 17 | 18 | public DBException(String message, Throwable cause) { 19 | super(message,cause); 20 | } 21 | 22 | 23 | public static class EngineGetVoid extends DBException{ 24 | public EngineGetVoid(){ 25 | super("Recid passed to Engine.get() does not exist. Possible data corruption!"); 26 | } 27 | } 28 | 29 | public static class EngineCompactUncommited extends DBException{ 30 | public EngineCompactUncommited(){ 31 | super("Engine.compact() called while there are uncommited data. Commit first, than compact!"); 32 | } 33 | } 34 | 35 | /** @see java.nio.channels.ClosedByInterruptException */ 36 | //TODO this thread was interrupted while doing IO? 37 | public static class VolumeClosedByInterrupt extends VolumeClosed{ 38 | public VolumeClosedByInterrupt(ClosedByInterruptException cause){ 39 | super("Some thread was interrupted while doing IO, and FileChannel was closed in result.", cause); 40 | } 41 | } 42 | 43 | public static class VolumeClosed extends DBException{ 44 | public VolumeClosed(IOException cause){ 45 | this("Volume (file or other device) was already closed.", cause); 46 | } 47 | 48 | protected VolumeClosed(String msg, IOException cause) { 49 | super(msg,cause); 50 | } 51 | } 52 | 53 | 54 | public static class VolumeIOError extends DBException{ 55 | public VolumeIOError(String msg){ 56 | super(msg); 57 | } 58 | 59 | public VolumeIOError(String msg, Throwable cause){ 60 | super(msg,cause); 61 | } 62 | 63 | public VolumeIOError(Throwable cause){ 64 | super("IO failed", cause); 65 | } 66 | } 67 | 68 | public static class VolumeEOF extends VolumeIOError { 69 | public VolumeEOF() { 70 | super("Beyond End Of File accessed"); 71 | } 72 | } 73 | 74 | public static class OutOfMemory extends VolumeIOError{ 75 | public OutOfMemory(Throwable e){ 76 | super( 77 | e.getMessage().equals("Direct buffer memory")? 78 | "Out of Direct buffer memory. Increase it with JVM option '-XX:MaxDirectMemorySize=10G'": 79 | e.getMessage(), 80 | e); 81 | } 82 | 83 | } 84 | 85 | public static class DataCorruption extends DBException{ 86 | public DataCorruption(String msg){ 87 | super(msg); 88 | } 89 | } 90 | 91 | public static class ChecksumBroken extends DataCorruption{ 92 | public ChecksumBroken(){ 93 | super("CRC checksum is broken"); 94 | } 95 | } 96 | 97 | public static class HeadChecksumBroken extends DataCorruption{ 98 | public HeadChecksumBroken(){ 99 | super("Head checksum broken, perhaps db was not closed correctly?"); 100 | } 101 | } 102 | 103 | public static class PointerChecksumBroken extends DataCorruption{ 104 | public PointerChecksumBroken(){ 105 | super("Bit parity in file pointer is broken, data possibly corrupted."); 106 | } 107 | } 108 | 109 | public static class Interrupted extends DBException { 110 | public Interrupted(InterruptedException e) { 111 | super("Thread interrupted",e); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/org/mapdb/TxMaker.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; 18 | 19 | 20 | import java.io.Closeable; 21 | import java.util.concurrent.ScheduledExecutorService; 22 | 23 | /** 24 | * Transaction factory 25 | * 26 | * @author Jan Kotek 27 | */ 28 | public class TxMaker implements Closeable { 29 | 30 | /** marker for deleted records*/ 31 | protected static final Object DELETED = new Object(); 32 | private final boolean txSnapshotsEnabled; 33 | private final boolean strictDBGet; 34 | protected ScheduledExecutorService executor; 35 | 36 | /** parent engine under which modifications are stored */ 37 | protected Engine engine; 38 | 39 | public TxMaker(Engine engine) { 40 | this(engine,false,false, null); 41 | } 42 | 43 | public TxMaker(Engine engine, boolean strictDBGet, boolean txSnapshotsEnabled, ScheduledExecutorService executor) { 44 | if(engine==null) throw new IllegalArgumentException(); 45 | if(!engine.canSnapshot()) 46 | throw new IllegalArgumentException("Snapshot must be enabled for TxMaker"); 47 | if(engine.isReadOnly()) 48 | throw new IllegalArgumentException("TxMaker can not be used with read-only Engine"); 49 | this.engine = engine; 50 | this.strictDBGet = strictDBGet; 51 | this.txSnapshotsEnabled = txSnapshotsEnabled; 52 | this.executor = executor; 53 | } 54 | 55 | 56 | public DB makeTx(){ 57 | Engine snapshot = engine.snapshot(); 58 | // if(txSnapshotsEnabled) 59 | // snapshot = new TxEngine(snapshot,false); //TODO 60 | return new DB(snapshot,strictDBGet,false,executor, true, null, 0, null, null); 61 | } 62 | 63 | public void close() { 64 | engine.close(); 65 | engine = null; 66 | } 67 | 68 | /** 69 | * Executes given block withing single transaction. 70 | * If block throws {@code TxRollbackException} execution is repeated until it does not fail. 71 | * 72 | * @param txBlock 73 | */ 74 | public void execute(TxBlock txBlock) { 75 | for(;;){ 76 | DB tx = makeTx(); 77 | try{ 78 | txBlock.tx(tx); 79 | if(!tx.isClosed()) 80 | tx.commit(); 81 | return; 82 | }catch(TxRollbackException e){ 83 | //failed, so try again 84 | if(!tx.isClosed()) tx.close(); 85 | } 86 | } 87 | } 88 | 89 | /** 90 | * Executes given block withing single transaction. 91 | * If block throws {@code TxRollbackException} execution is repeated until it does not fail. 92 | * 93 | * This method returns result returned by txBlock. 94 | * 95 | * @param txBlock 96 | */ 97 | public A execute(Fun.Function1 txBlock) { 98 | for(;;){ 99 | DB tx = makeTx(); 100 | try{ 101 | A a = txBlock.run(tx); 102 | if(!tx.isClosed()) 103 | tx.commit(); 104 | return a; 105 | }catch(TxRollbackException e){ 106 | //failed, so try again 107 | if(!tx.isClosed()) tx.close(); 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/StoreAppendTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.File; 6 | import java.io.IOException; 7 | import java.io.RandomAccessFile; 8 | 9 | import static org.junit.Assert.*; 10 | @SuppressWarnings({"rawtypes","unchecked"}) 11 | public class StoreAppendTest extends EngineTest{ 12 | 13 | 14 | File f = UtilsTest.tempDbFile(); 15 | 16 | 17 | @Override 18 | protected E openEngine() { 19 | StoreAppend s = new StoreAppend(f.getPath()); 20 | s.init(); 21 | return (E) s; 22 | } 23 | 24 | /* 25 | @Test 26 | public void compact_file_deleted(){ 27 | StoreAppend engine = new StoreAppend(f.getPath()); 28 | File f1 = engine.getFileFromNum(0); 29 | File f2 = engine.getFileFromNum(1); 30 | long recid = engine.put(111L, Serializer.LONG); 31 | Long i=0L; 32 | for(;i< StoreAppend.FILE_MASK+1000; i+=8){ 33 | engine.update(recid, i, Serializer.LONG); 34 | } 35 | i-=8; 36 | 37 | assertTrue(f1.exists()); 38 | assertTrue(f2.exists()); 39 | assertEquals(i, engine.get(recid, Serializer.LONG)); 40 | 41 | engine.commit(); 42 | assertTrue(f1.exists()); 43 | assertTrue(f2.exists()); 44 | assertEquals(i, engine.get(recid, Serializer.LONG)); 45 | 46 | engine.compact(); 47 | assertFalse(f1.exists()); 48 | assertTrue(f2.exists()); 49 | assertEquals(i, engine.get(recid, Serializer.LONG)); 50 | 51 | f1.delete(); 52 | f2.delete(); 53 | 54 | engine.close(); 55 | } 56 | 57 | @Test public void delete_files_after_close(){ 58 | File f = UtilsTest.tempDbFile(); 59 | File f2 = new File(f.getPath()+".0"); 60 | DB db = DBMaker.newAppendFileDB(f).deleteFilesAfterClose().make(); 61 | 62 | db.getHashMap("test").put("aa","bb"); 63 | db.commit(); 64 | assertTrue(f2.exists()); 65 | db.close(); 66 | assertFalse(f2.exists()); 67 | } 68 | 69 | @Test public void header_created() throws IOException { 70 | //check offset 71 | assertEquals(StoreAppend.RECID_LAST_RESERVED, e.maxRecid); 72 | assertEquals(1+8+2*StoreAppend.RECID_LAST_RESERVED, e.currPos); 73 | RandomAccessFile raf = new RandomAccessFile(e.getFileFromNum(0),"r"); 74 | //check header 75 | raf.seek(0); 76 | assertEquals(StoreAppend.HEADER, raf.readLong()); 77 | //check reserved recids 78 | for(int recid=1;recid<=StoreAppend.RECID_LAST_RESERVED;recid++){ 79 | assertEquals(0, e.index.getLong(recid*8)); 80 | assertEquals(recid+StoreAppend.RECIDP,raf.read()); //packed long 81 | assertEquals(0+StoreAppend.SIZEP,raf.read()); //packed long 82 | } 83 | 84 | assertEquals(StoreAppend.END+StoreAppend.RECIDP,raf.read()); //packed long 85 | //check recid iteration 86 | assertFalse(e.getFreeRecids().hasNext()); 87 | } 88 | 89 | @Test public void put(){ 90 | long oldPos = e.currPos; 91 | Volume vol = e.currVolume; 92 | assertEquals(0, vol.getUnsignedByte(oldPos)); 93 | 94 | long maxRecid = e.maxRecid; 95 | long value = 11111111111111L; 96 | long recid = e.put(value,Serializer.LONG); 97 | assertEquals(maxRecid+1, recid); 98 | assertEquals(e.maxRecid, recid); 99 | 100 | assertEquals(recid+StoreAppend.RECIDP, vol.getPackedLong(oldPos)); 101 | assertEquals(8+StoreAppend.SIZEP, vol.getPackedLong(oldPos+1)); 102 | assertEquals(value, vol.getLong(oldPos+2)); 103 | 104 | assertEquals(Long.valueOf(oldPos+1), e.indexInTx.get(recid)); 105 | e.commit(); 106 | assertEquals(oldPos+1, e.index.getLong(recid*8)); 107 | 108 | } 109 | 110 | 111 | @Override public void large_record_larger(){ 112 | //TODO ignored test 113 | } 114 | */ 115 | } 116 | -------------------------------------------------------------------------------- /src/test/java/examples/Huge_Insert.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import org.mapdb.*; 4 | 5 | import java.io.File; 6 | import java.io.IOException; 7 | import java.util.Collections; 8 | import java.util.Iterator; 9 | import java.util.Map; 10 | import java.util.Random; 11 | 12 | /** 13 | * Demonstrate how-to create large BTreeMap using data pump. 14 | * Typical usage is to import data set from external source. 15 | * 16 | * @author Jan Kotek 17 | */ 18 | public class Huge_Insert { 19 | 20 | public static void main(String[] args) throws IOException { 21 | 22 | /** max number of elements to import */ 23 | final long max = (int) 1e6; 24 | 25 | /** 26 | * Open database in temporary directory 27 | */ 28 | File dbFile = File.createTempFile("mapdb","temp"); 29 | DB db = DBMaker 30 | .fileDB(dbFile) 31 | /** disabling Write Ahead Log makes import much faster */ 32 | .transactionDisable() 33 | .make(); 34 | 35 | 36 | long time = System.currentTimeMillis(); 37 | 38 | /** 39 | * Source of data which randomly generates strings. 40 | * In real world this would return data from file. 41 | */ 42 | Iterator source = new Iterator() { 43 | 44 | long counter = 0; 45 | 46 | @Override public boolean hasNext() { 47 | return counter valueExtractor = new Fun.Function1() { 85 | @Override public Integer run(String s) { 86 | return s.hashCode(); 87 | } 88 | }; 89 | 90 | /** 91 | * Create BTreeMap and fill it with data 92 | */ 93 | Map map = db.treeMapCreate("map") 94 | .pumpSource(source,valueExtractor) 95 | //.pumpPresort(100000) // for presorting data we could also use this method 96 | .keySerializer(keySerializer) 97 | .make(); 98 | 99 | 100 | System.out.println("Finished; total time: "+(System.currentTimeMillis()-time)/1000+"s; there are "+map.size()+" items in map"); 101 | db.close(); 102 | 103 | } 104 | 105 | public static String randomString(int size) { 106 | String chars = "0123456789abcdefghijklmnopqrstuvwxyz !@#$%^&*()_+=-{}[]:\",./<>?|\\"; 107 | StringBuilder b = new StringBuilder(size); 108 | Random r = new Random(); 109 | for(int i=0;i 21 | * Compiler Configuration. There are some static final boolean fields, which describe features MapDB was compiled with. 22 | *

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

28 | * 29 | * Typical usage: 30 | *

31 | *
{@code
 32 |  *     if(CC.ASSERT && arg.calculateSize()!=33){  //calculateSize may take long time
 33 |  *         throw new IllegalArgumentException("wrong size");
 34 |  *     }
 35 |  * }
36 | * 37 | * 38 | * @author Jan Kotek 39 | */ 40 | public interface CC { 41 | 42 | /** 43 | * Compile with more assertions and verifications. 44 | * For example HashMap may check if keys implements hash function correctly. 45 | * This will slow down MapDB significantly. 46 | */ 47 | boolean ASSERT = true; 48 | 49 | boolean PARANOID = false; 50 | 51 | 52 | /** 53 | * Compile-in detailed log messages from store. 54 | */ 55 | boolean LOG_STORE = false; 56 | 57 | /** 58 | * Compile-in detailed log messages from Engine Wrappers 59 | */ 60 | boolean LOG_EWRAP = false; 61 | 62 | // /** 63 | // * Log lock/unlock events. Useful to diagnose deadlocks 64 | // */ 65 | // boolean LOG_LOCKS = false; 66 | // 67 | // /** 68 | // * If true MapDB will display warnings if user is using MapDB API wrong way. 69 | // */ 70 | // boolean LOG_HINTS = true; 71 | 72 | 73 | 74 | /** 75 | * Compile-in detailed log messages from HTreeMap. 76 | */ 77 | boolean LOG_HTREEMAP = false; 78 | 79 | 80 | /** 81 | *

82 | * Default concurrency level. Should be greater than number of threads accessing 83 | * MapDB concurrently. On other side larger number consumes more memory 84 | *

85 | * 86 | * This number must be power of two: {@code CONCURRENCY = 2^N} 87 | *

88 | */ 89 | int DEFAULT_LOCK_SCALE = 16; 90 | 91 | 92 | // int BTREE_DEFAULT_MAX_NODE_SIZE = 32; 93 | 94 | 95 | int DEFAULT_CACHE_SIZE = 2048; 96 | 97 | String DEFAULT_CACHE = DBMaker.Keys.cache_disable; 98 | 99 | /** default executor scheduled rate for {@link org.mapdb.Store.Cache.WeakSoftRef} */ 100 | long DEFAULT_CACHE_EXECUTOR_PERIOD = 1000; 101 | 102 | int DEFAULT_FREE_SPACE_RECLAIM_Q = 5; 103 | 104 | /** controls if locks used in MapDB are fair */ 105 | boolean FAIR_LOCKS = false; 106 | 107 | 108 | int VOLUME_PAGE_SHIFT = 20; // 1 MB 109 | 110 | boolean STORE_INDEX_CRC = false; //TODO move to feature bit field 111 | 112 | /** 113 | * Will print stack trace of all operations which are write any data at given offset 114 | * Used for debugging. 115 | */ 116 | long VOLUME_PRINT_STACK_AT_OFFSET = 0; 117 | 118 | 119 | long DEFAULT_HTREEMAP_EXECUTOR_PERIOD = 1000; 120 | long DEFAULT_STORE_EXECUTOR_SCHED_RATE = 1000; 121 | 122 | long DEFAULT_METRICS_LOG_PERIOD = 10000; 123 | 124 | boolean METRICS_CACHE = true; 125 | boolean METRICS_STORE = true; 126 | 127 | int DEFAULT_ASYNC_WRITE_QUEUE_SIZE = 1024; 128 | } 129 | 130 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/TxEngineTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | 6 | import java.util.Map; 7 | 8 | import static org.junit.Assert.*; 9 | 10 | public class TxEngineTest { 11 | 12 | TxEngine e; 13 | 14 | 15 | @Before public void init(){ 16 | Store store = new StoreWAL(null); 17 | store.init(); 18 | e = new TxEngine(store,true, CC.DEFAULT_LOCK_SCALE); 19 | } 20 | 21 | @Test public void update(){ 22 | long recid = e.put(111, Serializer.INTEGER); 23 | e.commit(); 24 | Engine snapshot = e.snapshot(); 25 | e.update(recid, 222, Serializer.INTEGER); 26 | assertEquals(Integer.valueOf(111), snapshot.get(recid, Serializer.INTEGER)); 27 | } 28 | 29 | @Test public void compareAndSwap(){ 30 | long recid = e.put(111, Serializer.INTEGER); 31 | e.commit(); 32 | Engine snapshot = e.snapshot(); 33 | e.compareAndSwap(recid, 111, 222, Serializer.INTEGER); 34 | assertEquals(Integer.valueOf(111), snapshot.get(recid, Serializer.INTEGER)); 35 | } 36 | 37 | @Test public void delete(){ 38 | long recid = e.put(111, Serializer.INTEGER); 39 | e.commit(); 40 | Engine snapshot = e.snapshot(); 41 | e.delete(recid, Serializer.INTEGER); 42 | assertEquals(Integer.valueOf(111), snapshot.get(recid, Serializer.INTEGER)); 43 | } 44 | 45 | @Test public void notExist(){ 46 | Engine snapshot = e.snapshot(); 47 | long recid = e.put(111, Serializer.INTEGER); 48 | assertNull(snapshot.get(recid, Serializer.INTEGER)); 49 | } 50 | 51 | 52 | @Test public void create_snapshot(){ 53 | Engine e = DBMaker.memoryDB().snapshotEnable().makeEngine(); 54 | Engine snapshot = TxEngine.createSnapshotFor(e); 55 | assertNotNull(snapshot); 56 | } 57 | 58 | @Test public void DB_snapshot(){ 59 | DB db = DBMaker.memoryDB().snapshotEnable().asyncWriteFlushDelay(100).transactionDisable().make(); 60 | long recid = db.getEngine().put("aa", Serializer.STRING_NOSIZE); 61 | DB db2 = db.snapshot(); 62 | assertEquals("aa", db2.getEngine().get(recid,Serializer.STRING_NOSIZE)); 63 | db.getEngine().update(recid, "bb",Serializer.STRING_NOSIZE); 64 | assertEquals("aa", db2.getEngine().get(recid, Serializer.STRING_NOSIZE)); 65 | } 66 | 67 | @Test public void DB_snapshot2(){ 68 | DB db = DBMaker.memoryDB().transactionDisable().snapshotEnable().make(); 69 | long recid = db.getEngine().put("aa",Serializer.STRING_NOSIZE); 70 | DB db2 = db.snapshot(); 71 | assertEquals("aa", db2.getEngine().get(recid,Serializer.STRING_NOSIZE)); 72 | db.getEngine().update(recid, "bb",Serializer.STRING_NOSIZE); 73 | assertEquals("aa", db2.getEngine().get(recid,Serializer.STRING_NOSIZE)); 74 | } 75 | 76 | 77 | @Test public void BTreeMap_snapshot(){ 78 | BTreeMap map = 79 | DBMaker.memoryDB().transactionDisable().snapshotEnable() 80 | .make().treeMap("aaa"); 81 | map.put("aa","aa"); 82 | Map map2 = map.snapshot(); 83 | map.put("aa","bb"); 84 | assertEquals("aa",map2.get("aa")); 85 | } 86 | 87 | @Test public void HTreeMap_snapshot(){ 88 | HTreeMap map = 89 | DBMaker.memoryDB().transactionDisable().snapshotEnable() 90 | .make().hashMap("aaa"); 91 | map.put("aa","aa"); 92 | Map map2 = map.snapshot(); 93 | map.put("aa", "bb"); 94 | assertEquals("aa",map2.get("aa")); 95 | } 96 | 97 | // @Test public void test_stress(){ 98 | // ExecutorService ex = Executors.newCachedThreadPool(); 99 | // 100 | // TxMaker tx = DBMaker.memoryDB().transactionDisable().makeTxMaker(); 101 | // 102 | // DB db = tx.makeTx(); 103 | // final long recid = 104 | // 105 | // final int threadNum = 32; 106 | // for(int i=0;i dbMap = db.treeMap("personAndCity"); 73 | 74 | // Add data 75 | Person bilbo = new Person("Bilbo","The Shire"); 76 | Person sauron = new Person("Sauron","Mordor"); 77 | Person radagast = new Person("Radagast","Crazy Farm"); 78 | 79 | dbMap.put("west",bilbo); 80 | dbMap.put("south",sauron); 81 | dbMap.put("mid",radagast); 82 | 83 | // Commit and close 84 | db.commit(); 85 | db.close(); 86 | 87 | 88 | // 89 | // Second option for using cystom values is to use your own serializer. 90 | // This usually leads to better performance as MapDB does not have to 91 | // analyze the class structure. 92 | // 93 | 94 | class CustomSerializer extends Serializer implements Serializable{ 95 | 96 | @Override 97 | public void serialize(DataOutput out, Person value) throws IOException { 98 | out.writeUTF(value.getName()); 99 | out.writeUTF(value.getCity()); 100 | } 101 | 102 | @Override 103 | public Person deserialize(DataInput in, int available) throws IOException { 104 | return new Person(in.readUTF(), in.readUTF()); 105 | } 106 | 107 | @Override 108 | public int fixedSize() { 109 | return -1; 110 | } 111 | 112 | } 113 | 114 | Serializer serializer = new CustomSerializer(); 115 | 116 | DB db2 = DBMaker.tempFileDB().make(); 117 | 118 | Map map2 = db2.hashMapCreate("map").valueSerializer(serializer).make(); 119 | 120 | map2.put("North", new Person("Yet another dwarf","Somewhere")); 121 | 122 | db2.commit(); 123 | db2.close(); 124 | 125 | 126 | } 127 | 128 | 129 | } 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/StoreDirectFreeSpaceTest.java: -------------------------------------------------------------------------------- 1 | //TODO reenable 2 | //package org.mapdb; 3 | // 4 | //import org.junit.Test; 5 | // 6 | //import java.util.*; 7 | // 8 | //import static org.junit.Assert.*; 9 | // 10 | //public class StoreDirectFreeSpaceTest { 11 | // 12 | // final long max = 100000; 13 | // 14 | // final Map> longStacks = new TreeMap >(); 15 | // 16 | // /* mock longStacks so their page allocations wont mess up tests */ 17 | // StoreDirect stub = new StoreDirect(null){ 18 | // { 19 | // structuralLock.lock(); 20 | // } 21 | // 22 | // private Deque stackList(long ioList) { 23 | // if(longStacks.get(ioList)==null) longStacks.put(ioList, new LinkedList()); 24 | // return longStacks.get(ioList); 25 | // } 26 | // 27 | // @Override 28 | // protected long longStackTake(long ioList, boolean recursive) { 29 | // Long r = stackList(ioList).pollLast(); 30 | // return r!=null?r:0; 31 | // } 32 | // 33 | // 34 | // @Override 35 | // protected void longStackPut(long ioList, long offset, boolean recursive) { 36 | // maxUsedIoList = Math.max(maxUsedIoList, ioList); 37 | // stackList(ioList).add(offset); 38 | // } 39 | // }; 40 | // 41 | // void fill(long... n){ 42 | // for(int i=0;i>>48; //size 54 | // b[i*2+1] = size; 55 | // b[0]+=size - (i==a.length-1 ? 0: 8); 56 | // b[i*2+2] = a[i] & StoreDirect.MOFFSET; //offset 57 | // } 58 | // 59 | // assertArrayEquals(n, b); 60 | // } 61 | // 62 | // long size(long i){ 63 | // return StoreDirect.size2ListIoRecid(i); 64 | // } 65 | // 66 | // @Test 67 | // public void simpleTake(){ 68 | // fill(1,2); 69 | // assertEquals(2, stub.longStackTake(1,false)); 70 | // } 71 | // 72 | // @Test 73 | // public void simpleSpaceAlloc(){ 74 | // long ioList = size(16); 75 | // fill(ioList,32); 76 | // check(16, 16,32); 77 | // } 78 | // 79 | // @Test 80 | // public void simpleGrow(){ 81 | // check(32,32,16); 82 | // check(16,16,48); 83 | // } 84 | // 85 | // @Test 86 | // public void largeGrow(){ 87 | // int size = StoreDirect.MAX_REC_SIZE+100; 88 | // check(size, StoreDirect.MAX_REC_SIZE, 16, 108, 16+StoreDirect.MAX_REC_SIZE+1); 89 | // } 90 | // 91 | // @Test public void reuse_after_full(){ 92 | // stub.physSize = max; 93 | // fill(size(1600),320); 94 | // check(1600,1600,320); 95 | // } 96 | // 97 | // @Test public void split_after_full(){ 98 | // stub.physSize = max; 99 | // fill(size(3200),320); 100 | // check(1600,1600,320); 101 | // check(1600,1600,320+1600); 102 | // assertLongStacksEmpty(); 103 | // } 104 | // 105 | // void assertLongStacksEmpty() { 106 | // for(Deque d:longStacks.values()){ 107 | // if(!d.isEmpty()) fail(); 108 | // } 109 | // } 110 | // 111 | // 112 | // @Test public void multi_linked(){ 113 | // int size = 16000+16000; 114 | // fill(size(16000),100000, size(16000),200000); 115 | // //TODO 116 | // } 117 | // 118 | // @Test public void in_memory_compact(){ 119 | // for(DB d: Arrays.asList(DBMaker.memoryDB().cacheDisable().make(), 120 | // DBMaker.memoryDB().transactionDisable().cacheDisable().make())){ 121 | // Map m = d.getTreeMap("aa"); 122 | // for(Integer i=0;i<10000;i++){ 123 | // m.put(i,i*10); 124 | // } 125 | // d.commit(); 126 | // d.compact(); 127 | // for(Integer i=0;i<10000;i++){ 128 | // assertEquals(i*10, m.get(i)); 129 | // } 130 | // } 131 | // } 132 | // 133 | // 134 | //} 135 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/Issue332Test.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.*; 6 | import java.util.Map; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | /* 11 | * Created by paspi on 26.05.2014. 12 | */ 13 | public class Issue332Test { 14 | 15 | // 4 length bytes will be prepended to this string: 000000ef 16 | final static String problem = "76fa135e7d216e829a53845a983469ac1e4edb6120b79667d667e7d4f8560101010100000022bf456901000000230000002102123eeaa90e2f5786ce028e60ec03702706dadecee373a90b09b88a99cc668f46ac3358c8ea6433279c678846fb6e06eeccd82e2fe888f2ac203476d3918cd405790100000038ffffff9e000000be438253be43825301000000109bf45901000000230000002102123eeaa90e2f5786ce028e60ec03702706dadecee373a90b09b88a99cc668f46ac38bf80f10129594a7e949cc43c3bd6f8670ba5ab59874305f6839406738a9cf90100000038ffffff9e00000081bd175381bd1753"; 17 | public static final Serializer.CompressionWrapper VALUE_SERIALIZER = new Serializer.CompressionWrapper(new TestSerializer()); 18 | 19 | public static final class TestSerializer extends Serializer implements Serializable { 20 | 21 | // http://stackoverflow.com/a/140430 22 | private static byte[] fromHexString(final String encoded) { 23 | if ((encoded.length() % 2) != 0) 24 | throw new IllegalArgumentException("Input string must contain an even number of characters"); 25 | 26 | final byte result[] = new byte[encoded.length()/2]; 27 | final char enc[] = encoded.toCharArray(); 28 | for (int i = 0; i < enc.length; i += 2) { 29 | StringBuilder curr = new StringBuilder(2); 30 | curr.append(enc[i]).append(enc[i + 1]); 31 | result[i/2] = (byte) Integer.parseInt(curr.toString(), 16); 32 | } 33 | return result; 34 | } 35 | 36 | // http://stackoverflow.com/a/13006907 37 | private static String bytArrayToHex(byte[] a) { 38 | StringBuilder sb = new StringBuilder(); 39 | for(byte b: a) 40 | sb.append(String.format("%02x", b&0xff)); 41 | return sb.toString(); 42 | } 43 | 44 | 45 | @Override 46 | public void serialize(DataOutput out, String value) throws IOException { 47 | byte [] buf = fromHexString(value); 48 | out.writeInt(buf.length); 49 | out.write(buf); 50 | } 51 | 52 | @Override 53 | public String deserialize(DataInput in, int available) throws IOException { 54 | int nsize = in.readInt(); 55 | byte[] buf = new byte[nsize]; 56 | in.readFully(buf); 57 | 58 | return bytArrayToHex(buf); 59 | } 60 | 61 | @Override 62 | public int fixedSize() { 63 | return -1; 64 | } 65 | } 66 | 67 | @Test 68 | public void run() throws IOException { 69 | File f = File.createTempFile("mapdb","mapdb"); 70 | DB db = DBMaker.fileDB(f) 71 | .closeOnJvmShutdown() 72 | .make(); 73 | 74 | Map testMap = db.hashMapCreate("testmap") 75 | .valueSerializer(VALUE_SERIALIZER) 76 | //.valueSerializer(new TestSerializer()) 77 | .makeOrGet(); 78 | 79 | testMap.put(1, problem); 80 | db.commit(); 81 | db.close(); 82 | 83 | db = null; 84 | testMap = null; 85 | 86 | //------------------------- 87 | db = DBMaker.fileDB(f) 88 | .closeOnJvmShutdown() 89 | .make(); 90 | testMap = db.hashMapCreate("testmap") 91 | .valueSerializer(VALUE_SERIALIZER) 92 | .makeOrGet(); 93 | String deserialized = testMap.get(1); 94 | 95 | db.close(); 96 | assertEquals(problem,deserialized); 97 | } 98 | 99 | @Test public void test_ser_itself(){ 100 | String other = UtilsTest.clone(problem, new TestSerializer()); 101 | assertEquals(problem, other); 102 | } 103 | 104 | @Test public void test_comp(){ 105 | String other = UtilsTest.clone(problem, VALUE_SERIALIZER); 106 | assertEquals(problem, other); 107 | } 108 | 109 | 110 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/TestTransactions.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.util.Map; 7 | 8 | /* 9 | * 10 | * @author Alan Franzoni 11 | */ 12 | public class TestTransactions { 13 | 14 | @Test 15 | public void testSameCollectionInsertDifferentValuesInDifferentTransactions() throws Exception { 16 | 17 | TxMaker txMaker = DBMaker 18 | .memoryDB() 19 | .makeTxMaker(); 20 | 21 | DB txInit = txMaker.makeTx(); 22 | Map mapInit = txInit.treeMap("testMap"); 23 | 24 | for (int i=0; i<1e4 ; i++ ) { 25 | mapInit.put(i, String.format("%d", i)); 26 | 27 | } 28 | txInit.commit(); 29 | 30 | DB tx1 = txMaker.makeTx(); 31 | DB tx2 = txMaker.makeTx(); 32 | 33 | 34 | Map map1 = tx1.treeMap("testMap"); 35 | 36 | map1.put(1, "asd"); 37 | 38 | tx1.commit(); 39 | System.out.println("tx1 commit succeeded, map size after tx1 commits: " + txMaker.makeTx().treeMap("testMap").size()); 40 | 41 | Map map2 = tx2.treeMap("testMap"); 42 | map2.put(10001, "somevalue"); 43 | 44 | // the following line throws a TxRollbackException 45 | tx2.commit(); 46 | txMaker.close(); 47 | } 48 | 49 | @Test 50 | public void testDifferentCollectionsInDifferentTransactions() throws Exception { 51 | 52 | TxMaker txMaker = DBMaker 53 | .memoryDB() 54 | .makeTxMaker(); 55 | 56 | DB txInit = txMaker.makeTx(); 57 | Map mapInit = txInit.treeMap("testMap"); 58 | Map otherMapInit = txInit.treeMap("otherMap"); 59 | 60 | for (int i=0; i<1e4 ; i++ ) { 61 | mapInit.put(i, String.format("%d", i)); 62 | otherMapInit.put(i, String.format("%d", i)); 63 | 64 | } 65 | 66 | txInit.commit(); 67 | 68 | DB tx1 = txMaker.makeTx(); 69 | DB tx2 = txMaker.makeTx(); 70 | 71 | 72 | Map map1 = tx1.treeMap("testMap"); 73 | 74 | map1.put(2, "asd"); 75 | 76 | tx1.commit(); 77 | 78 | Map map2 = tx2.treeMap("otherMap"); 79 | map2.put(20, "somevalue"); 80 | 81 | // the following line throws a TxRollbackException 82 | tx2.commit(); 83 | txMaker.close(); 84 | } 85 | 86 | @Test 87 | public void testSameCollectionModifyDifferentValuesInDifferentTransactions() throws Exception { 88 | 89 | TxMaker txMaker = DBMaker 90 | .memoryDB() 91 | .makeTxMaker(); 92 | 93 | DB txInit = txMaker.makeTx(); 94 | Map mapInit = txInit.treeMap("testMap"); 95 | 96 | for (int i=0; i<1e4 ; i++ ) { 97 | mapInit.put(i, String.format("%d", i)); 98 | 99 | } 100 | txInit.commit(); 101 | 102 | DB tx1 = txMaker.makeTx(); 103 | DB tx2 = txMaker.makeTx(); 104 | 105 | 106 | Map map1 = tx1.treeMap("testMap"); 107 | 108 | map1.put(1, "asd"); 109 | 110 | 111 | tx1.commit(); 112 | System.out.println("tx1 commit succeeded, map size after tx1 commits: " + txMaker.makeTx().treeMap("testMap").size()); 113 | 114 | Map map2 = tx2.treeMap("testMap"); 115 | map2.put(100, "somevalue"); 116 | 117 | // the following line throws a TxRollbackException 118 | tx2.commit(); 119 | txMaker.close(); 120 | } 121 | 122 | @Test 123 | public void testTransactionsDoingNothing() throws Exception { 124 | 125 | TxMaker txMaker = DBMaker 126 | .memoryDB() 127 | .makeTxMaker(); 128 | 129 | DB txInit = txMaker.makeTx(); 130 | Map mapInit = txInit.treeMap("testMap"); 131 | 132 | for (int i=0; i<1e4 ; i++ ) { 133 | mapInit.put(i, String.format("%d", i)); 134 | 135 | } 136 | txInit.commit(); 137 | 138 | 139 | DB tx1 = txMaker.makeTx(); 140 | DB tx2 = txMaker.makeTx(); 141 | 142 | 143 | Map map1 = tx1.treeMap("testMap"); 144 | 145 | tx1.commit(); 146 | 147 | Map map2 = tx2.treeMap("testMap"); 148 | 149 | // the following line throws a TxRollbackException 150 | tx2.commit(); 151 | txMaker.close(); 152 | } 153 | 154 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/ClosedThrowsExceptionTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.util.Map; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | /* 12 | * check that `IllegalAccessError` is thrown after DB was closed 13 | */ 14 | public abstract class ClosedThrowsExceptionTest { 15 | 16 | abstract DB db(); 17 | 18 | DB db; 19 | 20 | 21 | @Before public void init(){ 22 | db = db(); 23 | } 24 | 25 | @After public void close(){ 26 | db = null; 27 | } 28 | 29 | static public class Def extends ClosedThrowsExceptionTest{ 30 | @Override DB db() { 31 | return DBMaker.memoryDB().make(); 32 | } 33 | } 34 | 35 | static public class Async extends ClosedThrowsExceptionTest{ 36 | @Override DB db() { 37 | return DBMaker.memoryDB().asyncWriteEnable().make(); 38 | } 39 | } 40 | 41 | static public class NoCache extends ClosedThrowsExceptionTest{ 42 | @Override DB db() { 43 | return DBMaker.memoryDB().make(); 44 | } 45 | } 46 | 47 | static public class HardRefCache extends ClosedThrowsExceptionTest{ 48 | @Override DB db() { 49 | return DBMaker.memoryDB().cacheHardRefEnable().make(); 50 | } 51 | } 52 | 53 | static public class TX extends ClosedThrowsExceptionTest{ 54 | @Override DB db() { 55 | return DBMaker.memoryDB().makeTxMaker().makeTx(); 56 | } 57 | } 58 | 59 | static public class storeHeap extends ClosedThrowsExceptionTest{ 60 | @Override DB db() { 61 | return new DB(new StoreHeap(true,CC.DEFAULT_LOCK_SCALE,0)); 62 | } 63 | } 64 | 65 | @Test(expected = IllegalAccessError.class) 66 | public void closed_getHashMap(){ 67 | db.hashMap("test"); 68 | db.close(); 69 | db.hashMap("test"); 70 | } 71 | 72 | @Test() 73 | public void closed_getNamed(){ 74 | db.hashMap("test"); 75 | db.close(); 76 | assertEquals(null, db.getNameForObject("test")); 77 | } 78 | 79 | 80 | @Test(expected = IllegalAccessError.class) 81 | public void closed_put(){ 82 | Map m = db.hashMap("test"); 83 | db.close(); 84 | m.put("aa","bb"); 85 | } 86 | 87 | 88 | @Test(expected = IllegalAccessError.class) 89 | public void closed_remove(){ 90 | Map m = db.hashMap("test"); 91 | m.put("aa","bb"); 92 | db.close(); 93 | m.remove("aa"); 94 | } 95 | 96 | @Test(expected = IllegalAccessError.class) 97 | public void closed_close(){ 98 | Map m = db.hashMap("test"); 99 | m.put("aa","bb"); 100 | db.close(); 101 | db.close(); 102 | } 103 | 104 | @Test(expected = IllegalAccessError.class) 105 | public void closed_rollback(){ 106 | Map m = db.hashMap("test"); 107 | m.put("aa","bb"); 108 | db.close(); 109 | db.rollback(); 110 | } 111 | 112 | @Test(expected = IllegalAccessError.class) 113 | public void closed_commit(){ 114 | Map m = db.hashMap("test"); 115 | m.put("aa","bb"); 116 | db.close(); 117 | db.commit(); 118 | } 119 | 120 | @Test 121 | public void closed_is_closed(){ 122 | Map m = db.hashMap("test"); 123 | m.put("aa","bb"); 124 | db.close(); 125 | assertEquals(true,db.isClosed()); 126 | } 127 | 128 | @Test(expected = IllegalAccessError.class) 129 | public void closed_engine_get(){ 130 | long recid = db.getEngine().put("aa",Serializer.STRING); 131 | db.close(); 132 | db.getEngine().get(recid,Serializer.STRING); 133 | } 134 | 135 | @Test(expected = IllegalAccessError.class) 136 | public void closed_engine_put(){ 137 | db.close(); 138 | long recid = db.getEngine().put("aa",Serializer.STRING); 139 | } 140 | 141 | @Test(expected = IllegalAccessError.class) 142 | public void closed_engine_update(){ 143 | long recid = db.getEngine().put("aa",Serializer.STRING); 144 | db.close(); 145 | db.getEngine().update(recid, "aax", Serializer.STRING); 146 | } 147 | 148 | @Test(expected = IllegalAccessError.class) 149 | public void closed_engine_delete(){ 150 | long recid = db.getEngine().put("aa",Serializer.STRING); 151 | db.close(); 152 | db.getEngine().delete(recid, Serializer.STRING); 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/test/java/org/mapdb/QueuesTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.Queue; 9 | import java.util.concurrent.BlockingQueue; 10 | 11 | import static org.hamcrest.CoreMatchers.is; 12 | import static org.junit.Assert.*; 13 | 14 | @SuppressWarnings({"rawtypes","unchecked"}) 15 | public class QueuesTest { 16 | 17 | 18 | 19 | @Test public void stack_persisted(){ 20 | File f = UtilsTest.tempDbFile(); 21 | DB db = DBMaker.fileDB(f).transactionDisable().make(); 22 | Queue stack = db.getStack("test"); 23 | stack.add("1"); 24 | stack.add("2"); 25 | stack.add("3"); 26 | stack.add("4"); 27 | 28 | db.close(); 29 | db = DBMaker.fileDB(f).transactionDisable().deleteFilesAfterClose().make(); 30 | stack = db.getStack("test"); 31 | 32 | assertEquals("4",stack.poll()); 33 | assertEquals("3",stack.poll()); 34 | assertEquals("2",stack.poll()); 35 | assertEquals("1",stack.poll()); 36 | assertNull(stack.poll()); 37 | db.close(); 38 | } 39 | 40 | 41 | @Test public void queue_persisted(){ 42 | File f = UtilsTest.tempDbFile(); 43 | DB db = DBMaker.fileDB(f).transactionDisable().make(); 44 | Queue queue = db.getQueue("test"); 45 | queue.add("1"); 46 | queue.add("2"); 47 | queue.add("3"); 48 | queue.add("4"); 49 | 50 | db.close(); 51 | db = DBMaker.fileDB(f).transactionDisable().deleteFilesAfterClose().make(); 52 | queue = db.getQueue("test"); 53 | 54 | assertEquals("1", queue.poll()); 55 | assertEquals("2", queue.poll()); 56 | assertEquals("3", queue.poll()); 57 | assertEquals("4", queue.poll()); 58 | assertNull(queue.poll()); 59 | db.close(); 60 | } 61 | 62 | @Test public void circular_queue_persisted(){ 63 | //i put disk limit 4 objects , 64 | File f = UtilsTest.tempDbFile(); 65 | DB db = DBMaker.fileDB(f).transactionDisable().make(); 66 | Queue queue = db.createCircularQueue("test",null, 4); 67 | //when i put 6 objects to queue 68 | queue.add(0); 69 | queue.add(1); 70 | queue.add(2); 71 | queue.add(3); 72 | //now deletes 0 on first 73 | queue.add(4); 74 | //now deletes 1 75 | queue.add(5); 76 | 77 | db.close(); 78 | db = DBMaker.fileDB(f).transactionDisable().deleteFilesAfterClose().make(); 79 | queue = db.getCircularQueue("test"); 80 | 81 | assertEquals(2, queue.poll()); 82 | assertEquals(3, queue.poll()); 83 | assertEquals(4, queue.poll()); 84 | assertEquals(5, queue.poll()); 85 | assertNull(queue.poll()); 86 | db.close(); 87 | 88 | } 89 | 90 | @Test 91 | public void testMapDb() throws InterruptedException { 92 | DB database = DBMaker.memoryDB().make(); 93 | BlockingQueue queue = database.getQueue( "test-queue" ); 94 | queue.put( "test-value" ); 95 | database.commit(); 96 | assertThat( queue.take(), is( "test-value" ) ); 97 | database.commit(); 98 | database.close(); 99 | } 100 | 101 | @Test(timeout=100000) 102 | public void queueTakeRollback() throws IOException, InterruptedException { 103 | File f = File.createTempFile("mapdb","aa"); 104 | { 105 | DB db = DBMaker.fileDB(f).make(); 106 | boolean newQueue = !db.exists("test"); 107 | BlockingQueue queue = db.getQueue("test"); 108 | if (newQueue) { 109 | queue.add("abc"); 110 | db.commit(); 111 | } 112 | Object x = queue.take(); 113 | db.rollback(); 114 | x = queue.take(); 115 | 116 | System.out.println("got it"); 117 | db.close(); 118 | } 119 | 120 | { 121 | DB db = DBMaker.fileDB(f).make(); 122 | boolean newQueue = !db.exists("test"); 123 | BlockingQueue queue = db.getQueue("test"); 124 | if (newQueue) { 125 | queue.add("abc"); 126 | db.commit(); 127 | } 128 | Object x = queue.take(); 129 | db.rollback(); 130 | x = queue.take(); 131 | 132 | System.out.println("got it"); 133 | db.commit(); 134 | db.close(); 135 | } 136 | } 137 | } -------------------------------------------------------------------------------- /src/test/java/org/mapdb/AsyncWriteEngineTest.java: -------------------------------------------------------------------------------- 1 | package org.mapdb; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.util.ArrayList; 10 | import java.util.Map; 11 | import java.util.concurrent.ConcurrentHashMap; 12 | import java.util.concurrent.CountDownLatch; 13 | import java.util.concurrent.atomic.AtomicLong; 14 | 15 | import static org.junit.Assert.*; 16 | 17 | /* 18 | * @author Jan Kotek 19 | */ 20 | /* 21 | @SuppressWarnings({ "unchecked", "rawtypes" }) 22 | public class AsyncWriteEngineTest{ 23 | 24 | File index = UtilsTest.tempDbFile(); 25 | AsyncWriteEngine engine; 26 | 27 | @Before public void reopenStore() throws IOException { 28 | assertNotNull(index); 29 | if(engine !=null) 30 | engine.close(); 31 | engine = new AsyncWriteEngine( 32 | DBMaker.fileDB(index).transactionDisable().cacheDisable().makeEngine() 33 | ); 34 | } 35 | 36 | @After 37 | public void close(){ 38 | engine.close(); 39 | } 40 | 41 | 42 | @Test(timeout = 1000000) 43 | public void write_fetch_update_delete() throws IOException { 44 | long recid = engine.put("aaa", Serializer.STRING_NOSIZE); 45 | assertEquals("aaa", engine.get(recid, Serializer.STRING_NOSIZE)); 46 | reopenStore(); 47 | assertEquals("aaa", engine.get(recid, Serializer.STRING_NOSIZE)); 48 | engine.update(recid, "bbb", Serializer.STRING_NOSIZE); 49 | assertEquals("bbb", engine.get(recid, Serializer.STRING_NOSIZE)); 50 | reopenStore(); 51 | assertEquals("bbb", engine.get(recid, Serializer.STRING_NOSIZE)); 52 | 53 | } 54 | 55 | 56 | @Test(timeout = 0xFFFF) 57 | public void concurrent_updates_test() throws InterruptedException, IOException { 58 | final int threadNum = 16; 59 | final int updates = 1000; 60 | final CountDownLatch latch = new CountDownLatch(threadNum); 61 | final Map recids = new ConcurrentHashMap(); 62 | 63 | for(int i = 0;i long put(A value, Serializer serializer) { 102 | putCounter.incrementAndGet(); 103 | return super.put(value, serializer); 104 | } 105 | 106 | @Override 107 | public void update(long recid, A value, Serializer serializer) { 108 | putCounter.incrementAndGet(); 109 | super.update(recid, value, serializer); 110 | } 111 | 112 | }; 113 | AsyncWriteEngine a = new AsyncWriteEngine(t); 114 | byte[] b = new byte[124]; 115 | 116 | long max = 100; 117 | 118 | ArrayList l = new ArrayList(); 119 | for(int i=0;i100000 || size<6); 45 | assertEquals(b.pos,size); 46 | assertEquals(i | (size<<56), unpackLongBidi(b.buf,0)); 47 | assertEquals(i | (size<<56), unpackLongBidiReverse(b.buf, (int) size)); 48 | } 49 | } 50 | 51 | @Test public void parityBasic(){ 52 | for(long i=0;i>>48==0;i=i+1+i/10000){ 67 | DataIO.putSixLong(b,2,i); 68 | assertEquals(i, DataIO.getSixLong(b,2)); 69 | } 70 | } 71 | 72 | @Test public void testNextPowTwo(){ 73 | assertEquals(1, DataIO.nextPowTwo(1)); 74 | assertEquals(2, DataIO.nextPowTwo(2)); 75 | assertEquals(4, DataIO.nextPowTwo(3)); 76 | assertEquals(4, DataIO.nextPowTwo(4)); 77 | 78 | assertEquals(64, DataIO.nextPowTwo(33)); 79 | assertEquals(64, DataIO.nextPowTwo(61)); 80 | 81 | assertEquals(1024, DataIO.nextPowTwo(777)); 82 | assertEquals(1024, DataIO.nextPowTwo(1024)); 83 | 84 | assertEquals(1073741824, DataIO.nextPowTwo(1073741824-100)); 85 | assertEquals(1073741824, DataIO.nextPowTwo((int) (1073741824*0.7))); 86 | assertEquals(1073741824, DataIO.nextPowTwo(1073741824)); 87 | } 88 | 89 | @Test public void testNextPowTwo2(){ 90 | for(int i=1;i<1073750016;i+= 1 + i/100000){ 91 | int pow = nextPowTwo(i); 92 | assertTrue(pow>=i); 93 | assertTrue(Integer.bitCount(pow)==1); 94 | 95 | } 96 | } 97 | 98 | @Test public void packLongCompat() throws IOException { 99 | DataOutputByteArray b = new DataOutputByteArray(); 100 | b.packLong(2111L); 101 | b.packLong(100); 102 | b.packLong(1111L); 103 | 104 | DataInputByteArray b2 = new DataInputByteArray(b.buf); 105 | assertEquals(2111L, b2.unpackLong()); 106 | assertEquals(100L, b2.unpackLong()); 107 | assertEquals(1111L, b2.unpackLong()); 108 | 109 | DataInputByteBuffer b3 = new DataInputByteBuffer(ByteBuffer.wrap(b.buf),0); 110 | assertEquals(2111L, b3.unpackLong()); 111 | assertEquals(100L, b3.unpackLong()); 112 | assertEquals(1111L, b3.unpackLong()); 113 | } 114 | 115 | @Test public void packIntCompat() throws IOException { 116 | DataOutputByteArray b = new DataOutputByteArray(); 117 | b.packInt(2111); 118 | b.packInt(100); 119 | b.packInt(1111); 120 | 121 | DataInputByteArray b2 = new DataInputByteArray(b.buf); 122 | assertEquals(2111, b2.unpackInt()); 123 | assertEquals(100, b2.unpackInt()); 124 | assertEquals(1111, b2.unpackInt()); 125 | 126 | DataInputByteBuffer b3 = new DataInputByteBuffer(ByteBuffer.wrap(b.buf),0); 127 | assertEquals(2111, b3.unpackInt()); 128 | assertEquals(100, b3.unpackInt()); 129 | assertEquals(1111, b3.unpackInt()); 130 | } 131 | 132 | 133 | @Test public void testHexaConversion(){ 134 | byte[] b = new byte[]{11,112,11,0,39,90}; 135 | assertTrue(Serializer.BYTE_ARRAY.equals(b, DataIO.fromHexa(DataIO.toHexa(b)))); 136 | } 137 | } --------------------------------------------------------------------------------