|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Objectorg.mapdb.EngineWrapper
org.mapdb.AsyncWriteEngine
public class AsyncWriteEngine
Engine wrapper which provides asynchronous serialization and asynchronous write.
This class takes an object instance, passes it to background writer thread (using Write Queue)
where it is serialized and written to disk. Async write does not affect commit durability,
Write Queue is flushed into disk on each commit. Modified records are held in small instance cache,
until they are written into disk.
This feature is disabled by default and can be enabled by calling DBMaker.asyncWriteEnable().
Write Cache is flushed in regular intervals or when it becomes full. Flush interval is 100 ms by default and
can be controlled by DBMaker.asyncWriteFlushDelay(int). Increasing this interval may improve performance
in scenarios where frequently modified items should be cached, typically BTreeMap import where keys
are presorted.
Asynchronous write does not affect commit durability. Write Queue is flushed during each commit, rollback and close call.
Those method also block until all records are written.
You may flush Write Queue manually by using clearCache() method.
There is global lock which prevents record being updated while commit is in progress.
This wrapper starts one threads named `MapDB writer #N` (where N is static counter).
Async Writer takes modified records from Write Queue and writes them into store.
It also preallocates new recids, as finding empty `recids` takes time so small stash is pre-allocated.
It runs as `daemon`, so it does not prevent JVM to exit.
Asynchronous Writes have several advantages (especially for single threaded user). But there are two things
user should be aware of:
* Because data are serialized on back-ground thread, they need to be thread safe or better immutable.
When you insert record into MapDB and modify it latter, this modification may happen before item
was serialized and you may not be sure what version was persisted
* Inter-thread communication has some overhead.
There is also only single Writer Thread, which may create single bottle-neck.
This usually not issue for
single or two threads, but in multi-threaded environment it may decrease performance.
So in truly concurrent environments with many updates (network servers, parallel computing )
you should keep Asynchronous Writes disabled.
Engine,
EngineWrapper| Nested Class Summary | |
|---|---|
protected static class |
AsyncWriteEngine.WriterRunnable
|
| Nested classes/interfaces inherited from class org.mapdb.EngineWrapper |
|---|
EngineWrapper.CloseOnJVMShutdown, EngineWrapper.ImmutabilityCheckEngine, EngineWrapper.ReadOnlyEngine, EngineWrapper.SerializerCheckEngineWrapper, EngineWrapper.SynchronizedEngineWrapper |
| Field Summary | |
|---|---|
protected AtomicReference<CountDownLatch> |
action
|
protected CountDownLatch |
activeThreadsCount
number of active threads running, used to await thread termination on close |
protected int |
asyncFlushDelay
flush Write Queue every N milliseconds |
protected boolean |
closeInProgress
indicates that `close()` was called and background threads are being terminated |
protected ReentrantReadWriteLock |
commitLock
Each insert to Write Queue must hold read lock. |
protected int |
maxSize
|
protected AtomicInteger |
size
|
protected static AtomicLong |
threadCounter
ensures thread name is followed by number |
protected Throwable |
threadFailedException
If background thread fails with exception, it is stored here, and rethrown to all callers. |
protected static Object |
TOMBSTONE
used to signal that object was deleted |
protected LongConcurrentHashMap<Fun.Tuple2<Object,Serializer>> |
writeCache
Associates `recid` from Write Queue with record data and serializer. |
| Fields inherited from class org.mapdb.EngineWrapper |
|---|
CLOSED |
| Fields inherited from interface org.mapdb.Engine |
|---|
CATALOG_RECID, CHECK_RECORD, CLASS_INFO_RECID, LAST_RESERVED_RECID |
| Constructor Summary | |
|---|---|
AsyncWriteEngine(Engine engine)
|
|
AsyncWriteEngine(Engine engine,
int _asyncFlushDelay,
int queueSize,
Executor executor)
Construct new class and starts background threads. |
|
| Method Summary | ||
|---|---|---|
protected void |
checkState()
checks that background threads are ready and throws exception if not |
|
void |
clearCache()
clears any underlying cache |
|
void |
close()
Close store/cache. |
|
void |
commit()
Makes all changes made since the previous commit/rollback permanent. |
|
void |
compact()
This method blocks all put/update/delete operations until it finishes (via global ReadWrite Commit Lock). |
|
|
compareAndSwap(long recid,
A expectedOldValue,
A newValue,
Serializer<A> serializer)
Updates existing record in atomic (Compare And Swap) manner. |
|
|
delete(long recid,
Serializer<A> serializer)
Remove existing record from store/cache Recid must be a number returned by 'put' method. |
|
|
get(long recid,
Serializer<A> serializer)
Get existing record. |
|
|
put(A value,
Serializer<A> serializer)
Insert new record. |
|
void |
rollback()
Undoes all changes made in the current transaction. |
|
protected boolean |
runWriter()
runs on background thread. |
|
protected void |
startThreads(Executor executor)
Starts background threads. |
|
|
update(long recid,
A value,
Serializer<A> serializer)
Update existing record with new value. |
|
protected void |
waitForAction(int actionNumber)
|
|
| Methods inherited from class org.mapdb.EngineWrapper |
|---|
canRollback, canSnapshot, checkClosed, closeListenerRegister, closeListenerUnregister, getSerializerPojo, getWrappedEngine, isClosed, isReadOnly, preallocate, preallocate, snapshot |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Methods inherited from interface org.mapdb.Engine |
|---|
canRollback, canSnapshot, closeListenerRegister, closeListenerUnregister, getSerializerPojo, isClosed, isReadOnly, preallocate, preallocate, snapshot |
| Field Detail |
|---|
protected static final AtomicLong threadCounter
protected static final Object TOMBSTONE
protected final int maxSize
protected final AtomicInteger size
protected final LongConcurrentHashMap<Fun.Tuple2<Object,Serializer>> writeCache
protected final ReentrantReadWriteLock commitLock
protected final CountDownLatch activeThreadsCount
protected volatile Throwable threadFailedException
protected volatile boolean closeInProgress
protected final int asyncFlushDelay
protected final AtomicReference<CountDownLatch> action
| Constructor Detail |
|---|
public AsyncWriteEngine(Engine engine,
int _asyncFlushDelay,
int queueSize,
Executor executor)
engine - which stores data._asyncFlushDelay - flush Write Queue every N millisecondsexecutor - optional executor to run tasks. If null daemon threads will be createdpublic AsyncWriteEngine(Engine engine)
| Method Detail |
|---|
protected void startThreads(Executor executor)
executor - optional executor to run tasks, if null deamon threads will be created
protected boolean runWriter()
throws InterruptedException
InterruptedExceptionprotected void checkState()
public <A> long put(A value,
Serializer<A> serializer)
put in interface Engineput in class EngineWrappervalue - records to be addedserializer - used to convert record into/from binary form
public <A> A get(long recid,
Serializer<A> serializer)
get in interface Engineget in class EngineWrapperrecid - (record identifier) under which record was persistedserializer - used to deserialize record from binary form
public <A> void update(long recid,
A value,
Serializer<A> serializer)
update in interface Engineupdate in class EngineWrapperrecid - (record identifier) under which record was persisted.value - new record value to be storedserializer - used to serialize record into binary form
public <A> boolean compareAndSwap(long recid,
A expectedOldValue,
A newValue,
Serializer<A> serializer)
oldValue==expectedOldValue when old value is found in instance cacheoldValue using serializer and checking oldValue.equals(expectedOldValue)expectedOldValue using serializer and comparing binary array with already serialized oldValue
compareAndSwap in interface EnginecompareAndSwap in class EngineWrapperrecid - (record identifier) under which record was persisted.expectedOldValue - old value to be compared with existing recordnewValue - to be written if values are matchingserializer - used to serialize record into binary form
public <A> void delete(long recid,
Serializer<A> serializer)
delete in interface Enginedelete in class EngineWrapperrecid - (record identifier) under which was record persistedserializer - which may be used in some circumstances to deserialize and store old objectpublic void close()
NullPointerException
There is an configuration option DBMaker.closeOnJvmShutdown() which uses shutdown hook to automatically
close Engine when JVM shutdowns.
This method blocks until Write Queue is flushed and Writer Thread writes all records and finishes.
When this method was called `closeInProgress` is set and no record can be modified.
close in interface Engineclose in class EngineWrapperprotected void waitForAction(int actionNumber)
public void commit()
commit in interface Enginecommit in class EngineWrapperpublic void rollback()
UnsupportedOperationException.
This method blocks until Write Queue is cleared.
All put/update/delete methods are blocked while rollback is in progress (via global ReadWrite Commit Lock).
After this method returns, commit lock is released and other operations may continue
rollback in interface Enginerollback in class EngineWrapperpublic void compact()
compact in interface Enginecompact in class EngineWrapperpublic void clearCache()
clearCache in interface EngineclearCache in class EngineWrapper
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||