Hi,

There is ImmutablePath and MutablePath. ImmutablePath is used in OLTP and is 
much more efficient in terms of space & time than MutablePath. You can create 
either as you please you just do:

Path path = XXXPath.make()
path = path.extend(…)
path = path.extend(…)

However, I don't recommend you work at that level. What I would recommend you 
do is this:

public class MyBigSelectLabelStep<S,E> {

  Traverser traverser = this.starts.next();
  Map<String,Object> result = doLowLevelProviderSpecificStuff(traverser);
  traverser = traverser.split(result.get("a"), EmptyStep.instance()); // 
simulate GraphStep
  traverser.addLabels("a")
  traverser = traverser.split(result.get("b"), EmptyStep.instance()); // 
simulate VertexStep
  traverser.addLabels("b") 
  traverser = traverser.split(result, EmptyStep.instance()); // simulate 
SelectStep
  return traverser;

}

This handles all the low-level mechanisms of generating a traverser that looks 
like it went through multiple steps even though it only went through one. This 
is hand-typed from memory of the API so please be aware that I might have 
gotten an argument wrong or something. Also, out() is a FlatMapStep and thus, 
processes an iterator of results -- you will have to be smart to flatten that 
iterator… see FlatMapStep's implementation for how this is typically handled in 
TinkerPop.

HTH,
Marko. 

http://markorodriguez.com

On Apr 7, 2016, at 10:59 AM, pieter-gmail <pieter.mar...@gmail.com> wrote:

> Hi,
> 
> I have been working on this without using a custom traverser. It is fine
> but I do need to be able to set the path of the traverser.
> 
> We had a ticket for this previously here
> <https://issues.apache.org/jira/browse/TINKERPOP-766>. I mentioned there
> that I no longer needed the path setter and you mentioned that is ok but
> it was never done.
> 
> To give some background.
> 
> g.V(a1).as("a").out().as("b").select("a", "b")
> 
> This will be compiled to one step. i.e. This means that the collapsed
> steps label information is somewhat obfuscated and the path is
> incorrectly calculated by the traverser.
> However the label information is not lost and I recalculate the path but
> need to set it on the traverser.
> 
> Is it still ok to make the path mutable?
> 
> Thanks
> Pieter
> 
> On 30/03/2016 23:19, Marko Rodriguez wrote:
>> Hi,
>> 
>> So Titan does something similar where it takes a row in Cassandra and turns 
>> those into Traversers. It uses FlatMapStep to do so where the iterator in 
>> FlatMapStep is a custom iterator that knows how to do data conversions.
>> 
>> Would something like that help?
>> 
>> If not and you really need your own TraverserGenerator, then you can use 
>> reflection to set it in DefaultTraversal. Its a private member now.
>> 
>> Moving forward, I would highly recommend you don't create classes so low in 
>> the stack. Graph database providers should only create (if necessary):
>> 
>>      1. Steps that extend non-final TinkerPop steps.
>>      2. TraversalStrategies that implement ProviderOptimizationStrategy.
>>      3. Classes that extend Graph, Vertex, Edge, Property, VertexProperty, 
>> and GraphComputer.
>>      4. Their own InputFormat or InputRDD if they want to have Spark/Giraph 
>> work against them.
>> 
>> Anything beyond that (I think) is starting to get into murky territory.
>> 
>> Marko.
>> 
>> http://markorodriguez.com
>> 
>> On Mar 30, 2016, at 2:46 PM, pieter-gmail <pieter.mar...@gmail.com> wrote:
>> 
>>> Hi,
>>> 
>>> I need it to keep state. Mapping sql ResultSet's grid nature to a graph
>>> nature gets complex quickly and being able to store and manipulate the
>>> state of the traverser makes it easier. Also it was possible and the
>>> solution presented itself to me as such.
>>> 
>>> A single row i.e. AbstractStep.processNextStart() from a sql ResultSet
>>> might map to many traversers. This is the at the heart of what makes
>>> Sqlg a worthwhile enterprise. To fetch lots of data (reduce latency
>>> cost) in a denormalized manner and map it to a graph format.
>>> 
>>> To manage this I needed to store state and add a custom method
>>> "customSplit(...)". customSplit is similar to split() but it uses and
>>> updates the said state. The custom traverser also keeps additional state
>>> of where we are with respect to the processNextStart() (a sql row) as I
>>> need it in order to calculate the next traverser from the same row.
>>> 
>>> So if all this becomes impossible there is bound to be a different
>>> solution to the same problem but it would require quite some thinking
>>> and effort.
>>> 
>>> With a little bit of arrogance and ignorance, perhaps letting OLAP
>>> constraints leak into OLTP is not a good idea. I'd say OLTP is 99% of
>>> use-cases so whatever these serialization issues are they ought to be
>>> contained to OLAP.
>>> 
>>> Thanks
>>> Pieter
>>> 
>>> 
>>> 
>>> On 30/03/2016 21:38, Marko Rodriguez wrote:
>>>> Hello Pieter,
>>>> 
>>>>> In SqlgGraph 
>>>>> <https://github.com/pietermartin/sqlg/blob/schema/sqlg-core/src/main/java/org/umlg/sqlg/structure/SqlgGraph.java>
>>>>> in a static code block invokes
>>>>> 
>>>>> static {
>>>>> TraversalStrategies.GlobalCache.registerStrategies(Graph.class,
>>>>> TraversalStrategies.GlobalCache.getStrategies(Graph.class).clone().addStrategies(new
>>>>> SqlgVertexStepStrategy()));
>>>>> TraversalStrategies.GlobalCache.registerStrategies(Graph.class,
>>>>> TraversalStrategies.GlobalCache.getStrategies(Graph.class).clone().addStrategies(new
>>>>> SqlgGraphStepStrategy()));
>>>>> TraversalStrategies.GlobalCache.getStrategies(Graph.class).setTraverserGeneratorFactory(new
>>>>> SqlgTraverserGeneratorFactory());
>>>>> }
>>>> This all looks great exception the TraverserGeneratorFactory. Traverser 
>>>> classes are so low-level and so tied to serialization code in OLAP that I 
>>>> removed all concept of users able to create traverser species. I need full 
>>>> control at that level to maneuver.
>>>> 
>>>> I really need to create a section in the docs that says stuff like:
>>>> 
>>>>    * Graph System Providers: only implement steps that extend non-final 
>>>> TinkerPop-steps (e.g. GraphStep, VertexStep, etc.).
>>>>    * Graph Language Providers: only have Traversal.steps() that can be 
>>>> represented as a composition of TinkerPop-steps.
>>>> 
>>>> When providers get too low level, then its hard for us to maneuver and 
>>>> optimize and move forward with designs. There are so many assumption in 
>>>> the code that we make around Traverser instances, Step interfaces, etc. 
>>>> that if people just make new ones, then strategies, serialization, etc. 
>>>> breaks down.
>>>> 
>>>> The question I have, why do you have your own Traverser implementation? I 
>>>> can't imagine a reason for a provider needs their own traverser class. ??
>>>> 
>>>> Thanks,
>>>> Marko.
>>>> 
>>>> http://markorodriguez.com
>> 
> 

Reply via email to