org.mapdb.EngineWrapper Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2012 Jan Kotek
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapdb;
import java.io.IOError;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* EngineWrapper adapter. It implements all methods on Engine interface.
*
* @author Jan Kotek
*/
public class EngineWrapper implements Engine{
private Engine engine;
protected EngineWrapper(Engine engine){
if(engine == null) throw new IllegalArgumentException();
this.engine = engine;
}
@Override
public long preallocate(){
return getWrappedEngine().preallocate();
}
@Override
public void preallocate(long[] recids){
getWrappedEngine().preallocate(recids);
}
@Override
public long put(A value, Serializer serializer) {
return getWrappedEngine().put(value, serializer);
}
@Override
public A get(long recid, Serializer serializer) {
return getWrappedEngine().get(recid, serializer);
}
@Override
public void update(long recid, A value, Serializer serializer) {
getWrappedEngine().update(recid, value, serializer);
}
@Override
public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) {
return getWrappedEngine().compareAndSwap(recid, expectedOldValue, newValue, serializer);
}
@Override
public void delete(long recid, Serializer serializer) {
getWrappedEngine().delete(recid, serializer);
}
@Override
public void close() {
Engine e = engine;
if(e!=null)
e.close();
engine = CLOSED;
}
@Override
public boolean isClosed() {
return engine==CLOSED || engine==null;
}
@Override
public void commit() {
getWrappedEngine().commit();
}
@Override
public void rollback() {
getWrappedEngine().rollback();
}
@Override
public boolean isReadOnly() {
return getWrappedEngine().isReadOnly();
}
@Override
public boolean canRollback() {
return getWrappedEngine().canRollback();
}
@Override
public void clearCache() {
getWrappedEngine().clearCache();
}
@Override
public void compact() {
getWrappedEngine().compact();
}
@Override
public SerializerPojo getSerializerPojo() {
return getWrappedEngine().getSerializerPojo();
}
public Engine getWrappedEngine(){
return checkClosed(engine);
}
protected static V checkClosed(V v){
if(v==null) throw new IllegalAccessError("DB has been closed");
return v;
}
/**
* Wraps an Engine
and throws
* UnsupportedOperationException("Read-only")
* on any modification attempt.
*/
public static class ReadOnlyEngine extends EngineWrapper {
public ReadOnlyEngine(Engine engine){
super(engine);
}
@Override
public long preallocate() {
throw new UnsupportedOperationException("Read-only");
}
@Override
public void preallocate(long[] recids){
throw new UnsupportedOperationException("Read-only");
}
@Override
public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) {
throw new UnsupportedOperationException("Read-only");
}
@Override
public long put(A value, Serializer serializer) {
throw new UnsupportedOperationException("Read-only");
}
@Override
public void update(long recid, A value, Serializer serializer) {
throw new UnsupportedOperationException("Read-only");
}
@Override
public void delete(long recid, Serializer serializer){
throw new UnsupportedOperationException("Read-only");
}
@Override
public void commit() {
throw new UnsupportedOperationException("Read-only");
}
@Override
public void rollback() {
throw new UnsupportedOperationException("Read-only");
}
@Override
public boolean isReadOnly() {
return true;
}
}
public static class DebugEngine extends EngineWrapper{
final Queue records = new ConcurrentLinkedQueue();
protected static final class Record{
final long recid;
final String desc;
public Record(long recid, String desc) {
this.recid = recid;
this.desc = desc;
}
}
public DebugEngine(Engine engine) {
super(engine);
}
@Override
public long preallocate() {
long recid = super.preallocate();
records.add(new Record(recid,"PREALLOC"));
return recid;
}
@Override
public void preallocate(long[] recids) {
super.preallocate(recids);
for(long recid:recids)
records.add(new Record(recid,"PREALLOC"));
}
@Override
public long put(A value, Serializer serializer) {
long recid = super.put(value, serializer);
records.add(new Record(recid,
"INSERT \n val:"+value+"\n ser:"+serializer
));
return recid;
}
@Override
public A get(long recid, Serializer serializer) {
A ret = super.get(recid, serializer);
records.add(new Record(recid,
"GET \n val:"+ret+"\n ser:"+serializer
));
return ret;
}
@Override
public void update(long recid, A value, Serializer serializer) {
super.update(recid, value, serializer);
records.add(new Record(recid,
"UPDATE \n val:"+value+"\n ser:"+serializer
));
}
@Override
public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) {
final boolean ret = super.compareAndSwap(recid, expectedOldValue, newValue, serializer);
records.add(new Record(recid,"CAS "+ret+"\n newVal:"+newValue+"\n ser:"+serializer));
return ret;
}
@Override
public void delete(long recid, Serializer serializer){
super.delete(recid,serializer);
records.add(new Record(recid,"DEL"));
}
}
/**
* check if Record Instances were not modified while in cache.
* Usuful to diagnose strange problems with Instance Cache.
*/
public static class ImmutabilityCheckEngine extends EngineWrapper{
protected static class Item {
final Serializer serializer;
final Object item;
final int oldChecksum;
public Item(Serializer serializer, Object item) {
if(item==null || serializer==null) throw new AssertionError("null");
this.serializer = serializer;
this.item = item;
oldChecksum = checksum();
if(oldChecksum!=checksum()) throw new AssertionError("inconsistent serialization");
}
private int checksum(){
try {
DataOutput2 out = new DataOutput2();
serializer.serialize(out, item);
byte[] bb = out.copyBytes();
return Arrays.hashCode(bb);
}catch(IOException e){
throw new IOError(e);
}
}
void check(){
int newChecksum = checksum();
if(oldChecksum!=newChecksum) throw new AssertionError("Record instance was modified: \n "+item+"\n "+serializer);
}
}
protected LongConcurrentHashMap- items = new LongConcurrentHashMap
- ();
protected ImmutabilityCheckEngine(Engine engine) {
super(engine);
}
@Override
public A get(long recid, Serializer serializer) {
Item item = items.get(recid);
if(item!=null) item.check();
A ret = super.get(recid, serializer);
if(ret!=null) items.put(recid, new Item(serializer,ret));
return ret;
}
@Override
public long put(A value, Serializer serializer) {
long ret = super.put(value, serializer);
if(value!=null) items.put(ret, new Item(serializer,value));
return ret;
}
@Override
public void update(long recid, A value, Serializer serializer) {
Item item = items.get(recid);
if(item!=null) item.check();
super.update(recid, value, serializer);
if(value!=null) items.put(recid, new Item(serializer,value));
}
@Override
public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) {
Item item = items.get(recid);
if(item!=null) item.check();
boolean ret = super.compareAndSwap(recid, expectedOldValue, newValue, serializer);
if(ret && newValue!=null) items.put(recid, new Item(serializer,item));
return ret;
}
@Override
public void close() {
super.close();
for(Iterator
- iter = items.valuesIterator(); iter.hasNext();){
iter.next().check();
}
items.clear();
}
}
/** Engine wrapper with all methods synchronized on global lock, useful to diagnose concurrency issues.*/
public static class SynchronizedEngineWrapper extends EngineWrapper{
protected SynchronizedEngineWrapper(Engine engine) {
super(engine);
}
@Override
synchronized public long preallocate(){
return super.preallocate();
}
@Override
synchronized public void preallocate(long[] recids){
super.preallocate(recids);
}
@Override
synchronized public long put(A value, Serializer serializer) {
return super.put(value, serializer);
}
@Override
synchronized public A get(long recid, Serializer serializer) {
return super.get(recid, serializer);
}
@Override
synchronized public void update(long recid, A value, Serializer serializer) {
super.update(recid, value, serializer);
}
@Override
synchronized public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) {
return super.compareAndSwap(recid, expectedOldValue, newValue, serializer);
}
@Override
synchronized public void delete(long recid, Serializer serializer) {
super.delete(recid, serializer);
}
@Override
synchronized public void close() {
super.close();
}
@Override
synchronized public boolean isClosed() {
return super.isClosed();
}
@Override
synchronized public void commit() {
super.commit();
}
@Override
synchronized public void rollback() {
super.rollback();
}
@Override
synchronized public boolean isReadOnly() {
return super.isReadOnly();
}
@Override
synchronized public void compact() {
super.compact();
}
}
/** Checks that Serializer used to serialize item is the same as Serializer used to deserialize it*/
public static class SerializerCheckEngineWrapper extends EngineWrapper{
protected LongMap
recid2serializer = new LongConcurrentHashMap();
protected SerializerCheckEngineWrapper(Engine engine) {
super(engine);
}
synchronized protected void checkSerializer(long recid, Serializer serializer) {
Serializer other = recid2serializer.get(recid);
if(other!=null){
if( other!=serializer && other.getClass()!=serializer.getClass())
throw new IllegalArgumentException("Serializer does not match. \n found: "+serializer+" \n expected: "+other);
}else
recid2serializer.put(recid,serializer);
}
@Override
public A get(long recid, Serializer serializer) {
checkSerializer(recid, serializer);
return super.get(recid, serializer);
}
@Override
public void update(long recid, A value, Serializer serializer) {
checkSerializer(recid, serializer);
super.update(recid, value, serializer);
}
@Override
public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) {
checkSerializer(recid, serializer);
return super.compareAndSwap(recid, expectedOldValue, newValue, serializer);
}
@Override
public void delete(long recid, Serializer serializer) {
checkSerializer(recid, serializer);
recid2serializer.remove(recid);
super.delete(recid, serializer);
}
}
/** throws `IllegalArgumentError("already closed)` on all access */
public static final Engine CLOSED = new Engine(){
@Override
public long preallocate() {
throw new IllegalAccessError("already closed");
}
@Override
public void preallocate(long[] recids) {
throw new IllegalAccessError("already closed");
}
@Override
public long put(A value, Serializer serializer) {
throw new IllegalAccessError("already closed");
}
@Override
public A get(long recid, Serializer serializer) {
throw new IllegalAccessError("already closed");
}
@Override
public void update(long recid, A value, Serializer serializer) {
throw new IllegalAccessError("already closed");
}
@Override
public boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer serializer) {
throw new IllegalAccessError("already closed");
}
@Override
public void delete(long recid, Serializer serializer) {
throw new IllegalAccessError("already closed");
}
@Override
public void close() {
throw new IllegalAccessError("already closed");
}
@Override
public boolean isClosed() {
return true;
}
@Override
public void commit() {
throw new IllegalAccessError("already closed");
}
@Override
public void rollback() throws UnsupportedOperationException {
throw new IllegalAccessError("already closed");
}
@Override
public boolean isReadOnly() {
throw new IllegalAccessError("already closed");
}
@Override
public boolean canRollback() {
throw new IllegalAccessError("already closed");
}
@Override
public void clearCache() {
throw new IllegalAccessError("already closed");
}
@Override
public void compact() {
throw new IllegalAccessError("already closed");
}
@Override
public SerializerPojo getSerializerPojo() {
throw new IllegalAccessError("already closed");
}
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy