/*******************************************************************************
* Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License 3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
******************************************************************************/
package com.opendoorlogistics.core.tables.decorators.datastores.deepcopying;
import gnu.trove.map.hash.TIntObjectHashMap;
import java.lang.ref.SoftReference;
import com.opendoorlogistics.api.tables.ODLDatastore;
import com.opendoorlogistics.api.tables.ODLDatastoreAlterable;
import com.opendoorlogistics.api.tables.ODLListener;
import com.opendoorlogistics.api.tables.ODLTable;
import com.opendoorlogistics.api.tables.ODLTableAlterable;
import com.opendoorlogistics.api.tables.ODLTableDefinition;
import com.opendoorlogistics.api.tables.ODLTableReadOnly;
import com.opendoorlogistics.core.tables.decorators.datastores.SimpleAbstractDecorator;
public class OptimisedDeepCopierDecorator<T extends ODLTableDefinition> extends SimpleAbstractDecorator<T>{
private final ODLDatastoreAlterable<? extends T> decorated;
private final TIntObjectHashMap<SoftReference<T>> deepCopies = new TIntObjectHashMap<>();
public OptimisedDeepCopierDecorator(ODLDatastoreAlterable<? extends T> decorated) {
this.decorated = decorated;
}
@Override
public T createTable(String tablename, int id) {
T table = decorated.createTable(tablename, id);
if(table!=null){
return getTableByImmutableId(table.getImmutableId());
}
return null;
}
@Override
public void deleteTableById(int tableId) {
deepCopies.remove(tableId);
decorated.deleteTableById(tableId);
}
@Override
public boolean setTableName(int tableId, String newName) {
deepCopies.remove(tableId);
return decorated.setTableName(tableId, newName);
}
@Override
public void setFlags(long flags) {
decorated.setFlags(flags);
}
@Override
public synchronized ODLDatastoreAlterable<? extends T> deepCopyWithShallowValueCopy(boolean lazyCopy) {
if(!lazyCopy){
return decorated.deepCopyWithShallowValueCopy(lazyCopy);
}
OptimisedDeepCopy<T> ret = new OptimisedDeepCopy<>(getFlags());
for(int i =0 ; i< decorated.getTableCount(); i++){
T table = decorated.getTableAt(i);
int id = table.getImmutableId();
SoftReference<T> refCopy = deepCopies.get(id);
if(refCopy!=null){
T copy = refCopy.get();
if(copy!=null){
ret.addImmutableTable(copy);
continue;
}
}
// take new deep copy and save it for future use
@SuppressWarnings("unchecked")
T copy = (T)table.deepCopyWithShallowValueCopy();
deepCopies.put(id, new SoftReference<T>(copy));
ret.addImmutableTable(copy);
}
return ret;
}
@Override
public int getTableCount() {
return decorated.getTableCount();
}
@Override
public T getTableAt(int i) {
if(i<decorated.getTableCount()){
int id = decorated.getTableAt(i).getImmutableId();
// return the table decoratoe
return super.getTableByImmutableId(id);
}
return null;
}
@Override
public void addListener(ODLListener tml, int... tableIds) {
decorated.addListener(tml, tableIds);
}
@Override
public void removeListener(ODLListener tml) {
decorated.removeListener(tml);
}
@Override
public void disableListeners() {
decorated.disableListeners();
}
@Override
public void enableListeners() {
decorated.enableListeners();
}
@Override
public void startTransaction() {
decorated.startTransaction();
}
@Override
public void endTransaction() {
decorated.endTransaction();
}
@Override
public boolean isInTransaction() {
return decorated.isInTransaction();
}
@Override
public void rollbackTransaction() {
decorated.rollbackTransaction();
}
@Override
public boolean isRollbackSupported() {
return decorated.isRollbackSupported();
}
@Override
public long getFlags() {
return decorated.getFlags();
}
@Override
protected ODLTableReadOnly readOnlyTable(int tableId) {
return (ODLTableReadOnly)decorated.getTableByImmutableId(tableId);
}
@Override
protected ODLTableDefinition definition(int tableId) {
return decorated.getTableByImmutableId(tableId);
}
@Override
protected synchronized ODLTable writable(int tableId) {
deepCopies.remove(tableId);
return (ODLTable) decorated.getTableByImmutableId(tableId);
}
@Override
protected synchronized ODLTableAlterable alterable(int tableId) {
deepCopies.remove(tableId);
return (ODLTableAlterable) decorated.getTableByImmutableId(tableId);
}
@Override
public boolean getTableExists(int tableId) {
return decorated.getTableByImmutableId(tableId)!=null;
}
@Override
public ODLTableDefinition deepCopyWithShallowValueCopy(int tableId) {
ODLTableDefinition t = decorated.getTableByImmutableId(tableId);
if(t!=null){
return t.deepCopyWithShallowValueCopy();
}
return null;
}
}