Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Join: use soft reference delegates for instances #31

Closed
wants to merge 10 commits into from
4 changes: 4 additions & 0 deletions common/plugins/eu.esdihumboldt.hale.common.align/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,10 @@
allowAll="false"
class="eu.esdihumboldt.hale.common.align.transformation.function.impl.NoResultException">
</allow>
<allow
allowAll="false"
class="eu.esdihumboldt.hale.common.align.transformation.function.impl.FamilyInstanceDelegate">
</allow>
</extension>

</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2016 Data Harmonisation Panel
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* wetransform GmbH
*/

package eu.esdihumboldt.hale.common.align.transformation.function.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import eu.esdihumboldt.hale.common.instance.model.FamilyInstance;
import eu.esdihumboldt.hale.common.instance.model.InstanceCollection;
import eu.esdihumboldt.hale.common.instance.model.InstanceReference;
import eu.esdihumboldt.hale.common.instance.model.impl.SoftInstanceDelegate;

/**
* Family instance delegating to a soft reference that is refreshed via an
* InstanceReference.
*
* @author Simon Templer
*/
public class FamilyInstanceDelegate extends SoftInstanceDelegate implements FamilyInstance {

private final Collection<FamilyInstance> children;

/**
* Constructs the delegating instance.
*
* @param ref the instance reference
* @param collection the instance collection to resolved the reference from
*/
public FamilyInstanceDelegate(InstanceReference ref, InstanceCollection collection) {
super(ref, collection);
children = new ArrayList<FamilyInstance>();
}

/**
* @see FamilyInstance#getChildren()
*/
@Override
public Collection<FamilyInstance> getChildren() {
return Collections.unmodifiableCollection(children);
}

/**
*
* @see FamilyInstance#addChild(FamilyInstance)
*/
@Override
public void addChild(FamilyInstance child) {
children.add(child);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#Updated from default preferences Jul 24, 2013 2:15:11 PM
#Wed Jul 24 14:15:11 CEST 2013
#Updated from default preferences Jul 11, 2016 3:40:58 PM
#Mon Jul 11 15:40:58 CEST 2016
eclipse.preferences.version=1
org.eclipse.jdt.core.builder.cleanOutputFolder=clean
org.eclipse.jdt.core.builder.duplicateResourceTask=warning
Expand All @@ -20,9 +20,10 @@ org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
Expand Down Expand Up @@ -107,7 +108,7 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Bundle-Name: Instance model based on Orient DB
Bundle-SymbolicName: eu.esdihumboldt.hale.common.instance.orient;singleton:=true
Bundle-Version: 2.9.5.qualifier
Bundle-Vendor: data harmonisation panel
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: eu.esdihumboldt.hale.common.instance;bundle-version="2.5.0",
com.vividsolutions.jts;bundle-version="1.12.0",
eu.esdihumboldt.hale.common.schema;bundle-version="2.5.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,7 @@ public Instance next() {
allowUpdate = true; // allow updating in hasNext
Instance instance = new OInstance(doc, getCurrentType(), ref.getDatabase(),
dataSet);
handle.addReference(instance);
return instance;
return handle.addInstance(instance);
}
else {
throw new IllegalStateException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,22 @@
package eu.esdihumboldt.hale.common.instance.orient.storage;

import java.lang.ref.Reference;
import java.util.Arrays;
import java.util.Set;

import javax.xml.namespace.QName;

import com.google.common.base.FinalizablePhantomReference;
import com.google.common.base.FinalizableReferenceQueue;
import com.google.common.collect.Sets;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;

import de.fhg.igd.slf4jplus.ALogger;
import de.fhg.igd.slf4jplus.ALoggerFactory;
import eu.esdihumboldt.hale.common.instance.model.Group;
import eu.esdihumboldt.hale.common.instance.model.Instance;
import eu.esdihumboldt.hale.common.instance.model.impl.GroupDecorator;
import eu.esdihumboldt.hale.common.instance.model.impl.InstanceDecorator;

/**
* Database handle that manages objects referencing the database object. It will
Expand Down Expand Up @@ -80,7 +87,10 @@ public void finalizeReferent() {
}

/**
* Add an object that references the database connection
* Add an object that references the database connection.
*
* It is preferred to use {@link #addInstance(Instance)} or
* {@link #addGroup(Group)} instead.
*
* @param object the object referencing the database
*/
Expand All @@ -98,6 +108,77 @@ public void finalizeReferent() {
count++;
}

/**
* Augment an instance and add a reference for the database connection.
* Makes sure child instances or groups also reference the database
* connection.
*
* @param instance the instance to augment
* @return the augmented instance
*/
public Instance addInstance(Instance instance) {
if (instance == null) {
return null;
}

Instance result = new InstanceDecorator(instance) {

@Override
public Object[] getProperty(QName propertyName) {
return augmentValues(getOriginalInstance().getProperty(propertyName));
}

};
addReference(result);
return result;
}

/**
* Augment a group and add a reference for the database connection. Makes
* sure child instances or groups also reference the database connection.
*
* @param group the group to augment
* @return the augmented group
*/
public Group addGroup(Group group) {
if (group == null) {
return null;
}

Group result = new GroupDecorator(group) {

@Override
public Object[] getProperty(QName propertyName) {
return augmentValues(getOriginalGroup().getProperty(propertyName));
}

};
addReference(result);
return result;
}

/**
* Augment an array of values.
*
* @param values the values to augment
* @return the augmented objects
*/
protected Object[] augmentValues(Object[] values) {
if (values == null) {
return null;
}

return Arrays.stream(values).map(value -> {
if (value instanceof Instance) {
return addInstance((Instance) value);
}
if (value instanceof Group) {
return addGroup((Group) value);
}
return value;
}).toArray();
}

private synchronized void removeReference() {
count--;
tryClose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import eu.esdihumboldt.hale.common.instance.model.DataSet;
import eu.esdihumboldt.hale.common.instance.model.Instance;
import eu.esdihumboldt.hale.common.instance.model.InstanceReference;
import eu.esdihumboldt.hale.common.instance.model.impl.InstanceDecorator;
import eu.esdihumboldt.hale.common.instance.orient.OInstance;
import eu.esdihumboldt.hale.common.schema.model.TypeDefinition;
import net.jcip.annotations.Immutable;
Expand Down Expand Up @@ -124,6 +125,10 @@ public static InstanceReference createReference(Instance instance) {
"Instance data set may not be null for retrieving reference");
}

while (instance instanceof InstanceDecorator) {
instance = ((InstanceDecorator) instance).getOriginalInstance();
}

OInstance inst = (OInstance) instance;
ORID id = inst.getDocument().getIdentity();

Expand All @@ -147,18 +152,7 @@ public Instance load(LocalOrientDB lodb, Object owner) {
if (document != null) {
OInstance instance = new OInstance(document, getTypeDefinition(), db.getDatabase(),
getDataSet());
handle.addReference(instance);
return instance;
/*
* Alternative: Returning a copy of the instance.
*
* But this can be very expensive if dealing with an instance
* with deep sub-structures. Example: A Merge on ~150 GML
* features took ~200 times longer (over 6 minutes instead of 2
* seconds) when copying instances that were retrieved through
* instance references.
*/
// return new DefaultInstance(instance);
return handle.addInstance(instance);
}
else
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ public Instance next() {
TypeDefinition type = types.getType(typeName);
// TODO react in case it is not found?
Instance instance = new OInstance(doc, type, ref.getDatabase(), dataSet);
handle.addReference(instance);
return instance;
return handle.addInstance(instance);
} catch (DecoderException e) {
throw new IllegalStateException("Failed to decode instance type", e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2016 wetransform GmbH
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* wetransform GmbH <http://www.wetransform.to>
*/

package eu.esdihumboldt.hale.common.instance.model.impl;

import javax.xml.namespace.QName;

import eu.esdihumboldt.hale.common.instance.model.Group;
import eu.esdihumboldt.hale.common.schema.model.DefinitionGroup;

/**
* Group decorator class.
*
* @author Simon Templer
*/
public class GroupDecorator implements Group {

private final Group group;

/**
* Constructs the decorator with the given group.
*
* @param group the group to decorate
*/
public GroupDecorator(Group group) {
this.group = group;
}

/**
* Returns the original group.
*
* @return the original group
*/
public Group getOriginalGroup() {
return group;
}

@Override
public Object[] getProperty(QName propertyName) {
return group.getProperty(propertyName);
}

@Override
public Iterable<QName> getPropertyNames() {
return group.getPropertyNames();
}

@Override
public DefinitionGroup getDefinition() {
return group.getDefinition();
}

}
Loading