You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jena.apache.org by "Andy Seaborne (JIRA)" <ji...@apache.org> on 2014/08/12 12:57:13 UTC
[jira] [Comment Edited] (JENA-763) Transforms should interact
better with custom operators
[ https://issues.apache.org/jira/browse/JENA-763?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14093954#comment-14093954 ]
Andy Seaborne edited comment on JENA-763 at 8/12/14 10:57 AM:
--------------------------------------------------------------
I'm not clear what the issue is here in detail -- is it the case of the quad
transform itself applied an algebra expression involving OpExt and also the
OpExt is quad sensitive or are there other transforms that would have state?
A real example would help.
>From the email thread, I don't understand about applying the quad
transform mid-optimization, after some local {{OpExt}} has been introduced.
Is there a reason not to do the quad transform first, then work entirely on
the quad form?
The quad transform state does not persist after the
transform is applied, but I think the only information lost is the exact
location of the {{(graph))}} ops although we could add a new algebra
operation to record that. In fact, there is something to do this already
-- {{OpLabel}} whose execution is simply to execute the sub-op. The idea
of "label" is to add info to the algebra tree without adding execution.
If the access to the quad transform class were opened up, an application
could write a subclass of the engine {{TransformQuadGraph}} and get access
to the state (neess to be made protected) and implement
{{transform(OpExt)}}. There is an interaction of the vistor/transform
pattern and subclassing from {{OpExt}} that means sometimes the transform
itself needs to deal with {{OpExt}}, not call {{OpExt.apply}}. It comes
down to the fact that visitor know all the types so it does not work with
class abstraction by subclassing {{OpExt}}. That's the way I envisaged
{{OpExt}} to be handled sometimes, not just via {{Transform.apply}}.
Better designs welcome!
* Is this specific to quad transformation or is there another real case?
* Is the assumption that the quad transform is done first not reasonable in
some use case?
was (Author: andy.seaborne):
I'm not clear what the issue is here in detail -- is it the case of the quad
transform itself applied an algebra expression involving OpExt and also the
OpExt is quad sensitive or are there other transforms that would have state?
A real example would help.
>From the email thread, I don't understand about applying the quad
transform mid-optimization, after some local {{OpExt}} has been introduced.
Is there a reason not to do the quad transform first, then work entirely on
the quad form?
The quad transform state does not persist after the
transform is applied, but I think the only information lost is the exact
location of the {{(graph))}} ops although we could add a new algebra
operation to record that. In fact, there is something to do this already
-- {{OpLabel}} whose execution is simply to execute the sub-op. The idea
of "label" is to add info to the algebra tree without adding execution.
If the access to the quad transform class were opened up, an application
could write a subclass of the engine {{TransformQuadGraph}} and get access
to the state (neess to be made protected) and implement
{{transform(OpExt)}}. There is an interaction of the vistor/transform
pattern and subclassing from {{OpExt}} that means sometimes the transform
itself needs to deal with {{OpExt}}, not call {{OpExt.apply}}. It comes
down to the fact that visitor know all the types so it does not work with
class abstraction by subclassing {{OpExt}}. That's the way I envisaged
{{OpExt}}s to be handled sometimes, not just via {{Transform.apply}}.
Better designs welcome!
* Is this specifc to quad transformation or is there another real case?
* Is the assumption that the quad transform is done first not reasonable in
some use case?
> Transforms should interact better with custom operators
> -------------------------------------------------------
>
> Key: JENA-763
> URL: https://issues.apache.org/jira/browse/JENA-763
> Project: Apache Jena
> Issue Type: Improvement
> Components: ARQ
> Affects Versions: Jena 2.12.0
> Reporter: Rob Vesse
>
> As already discussed briefly on the mailing list thread How to safely apply transforms to custom algebra operators? (http://s.apache.org/custom-algebra-transform) making some transforms pass correctly through custom algebra operators.
> {{TransformCopy}} defers the {{copy(OpExt ext)}} implementation back to the {{apply()}} method of {{OpExt}} which means a custom operator can do something simple like the following:
> {noformat}
> @Override
> public Op apply(Transform transform)
> {
> // This is required in order to not block optimizations
> return new CustomOperator(Transformer.transform(transform, this.subOp), this.customParams);
> }
> {noformat}
> Which will work correctly for stateless transforms but fails for transforms like {{Algebra.toQuadForm()}} which rely on external state. In the specific case of quad form transformation the external state is tracked by before and after visitors that are applied as the {{ApplyTransformVisitor}} works down the algebra with the state being used by the actual transform as it comes back up the algebra. However when passed through a custom operator there is no way to pass through the external state trackers and so inside the custom operator the transform may be accessing incorrect state.
> There are a couple of options for fixing this:
> # Fix this specific case by rewriting the quad form transform such that it does not rely on external state tracking (not sure that this is even feasible)
> # Revise the API for transforming {{OpExt}} so external state can also be passed where necessary
> Both options have difficulties and it may be possible to make simpler changes that allow the specific case of quad form transformations to be fixed without changing the public API.
> Another approach would be to have the quad form transform be a public class and provided public accessors to its external state such that a custom operator could specifically recognise it and special case it such that the external state tracking was passed onwards. More generally perhaps a marker interface {{StatefulTransform}} could be added which would provide a standard way to recognise transforms that may have this problem and provide access to the state trackers necessary to pass these through custom operators correctly. Additionally there could be overloads of {{Transformer.transform(Transform)}} i.e. {{Transformer.transform(StatefulTransform)}} that would wire things up appropriately allowing the existing basic approach for custom operators outlined above continue to work without special cases.
--
This message was sent by Atlassian JIRA
(v6.2#6252)