[ 
https://issues.apache.org/jira/browse/TINKERPOP3-479?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14388791#comment-14388791
 ] 

Tim Stewart commented on TINKERPOP3-479:
----------------------------------------

Here's one potential implementation:

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

/**
 * An ad hoc Element class (to be replaced with real Element class).
 */
class Element {
    private String key;
    private Object value;

    public Element(
            final String key,
            final Object value
    ) {
        this.key = Objects.requireNonNull(key);
        this.value = Objects.requireNonNull(value);
    }

    @Override
    public String toString() {
        return String.format("Element [key=%s, value=%s]", key, value);
    }
}

/**
 * An ad hoc Vertex class (to be replaced with real Vertex class).
 */
class Vertex extends Element {
    public Vertex(final String key, final Object value) {
        super(key, value);
    }
}

/**
 * The base class for objects returned by ensureVertex.
 */
class Result<T extends Element> {
    // The element that was found or created.
    private final T element;

    // true iff the element was created.
    private final boolean wasCreated;

    public Result(final T element, final boolean wasCreated) {
        this.element = Objects.requireNonNull(element);
        this.wasCreated = wasCreated;
    }

    public T getElement() {
        return element;
    }

    public boolean wasFound() {
        return !wasCreated;
    }
    
    public boolean wasCreated() {
        return wasCreated;
    }

    public T ifCreated(Consumer<T> func) {
        if (wasCreated) {
            func.accept(element);
        }

        return element;
    }

    public T ifFound(Consumer<T> func) {
        if (!wasCreated) {
            func.accept(element);
        }

        return element;
    }
}

/**
 * An ad hoc Graph class that provides a ensureVertex method.
 */
class Graph {
    private final Map<String, Vertex> vs = new HashMap<>();

    Result<Vertex> ensureVertex(final String key, final Object value) {
        if (vs.containsKey(key)) {
            final Vertex el = vs.get(key);
            return new Result(el, true);
        } else {
            final Vertex v = new Vertex(key, value);
            vs.put(key, v);
            return new Result(v, false);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        final Graph g = new Graph();

        // If you don't care if the element was created, but you just want the 
element.
        final Vertex v1 = g.ensureVertex("unique", "the value").getElement();

        // Example of when the vertex is created.  The lambda function is 
called.
        final Vertex v2 = g.ensureVertex("key", "value").ifCreated(x -> {
            System.out.println(String.format("Created!: %s", x));
        });

        // Example of when the vertex is not created.  The lambda function is 
not called.
        final Vertex v3 = g.ensureVertex("key", "value").ifCreated(x -> {
            // Won't print.
            System.out.println(String.format("Created Again!: %s", x));
        });

        // Example of when the vertex is found.  The lambda function is called.
        final Vertex v4 = g.ensureVertex("key", "value").ifFound(x -> {
            System.out.println(String.format("Should not be Found!: %s", x));
        });

        // Example of when the vertex is not found.  The lambda function is not 
called.
        final Vertex v5 = g.ensureVertex("key2", "value").ifFound(x -> {
            // Won't print.
            System.out.println(String.format("Found!: %s", x));
        });

        // Example of when the vertex is not found.  The lambda function is not 
called.
        final Result<Vertex> res1 = g.ensureVertex("key2", "value");

        // If you want to to do two different things based on whether or not it 
was created...
        if (res1.wasCreated()) {
            System.out.println(String.format("Created!: %s", 
res1.getElement()));
        } else {
            System.out.println(String.format("Not Created!: %s", 
res1.getElement()));
        }
    }
}


> Consider Providing "getOrCreate" Functionality
> ----------------------------------------------
>
>                 Key: TINKERPOP3-479
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP3-479
>             Project: TinkerPop 3
>          Issue Type: Improvement
>          Components: structure
>            Reporter: stephen mallette
>
> One of the most commonly written functions used is good ol' "getOrCreate" 
> where you want to get a {{Vertex}} if it exists or create it with supplied 
> properties if it does not.  We currently have a "helper" function for this on 
> {{ElementHelper}} 
> https://github.com/tinkerpop/tinkerpop3/blob/6d0f00865f673cb0739f6f310e1868425f732924/gremlin-core/src/main/java/com/tinkerpop/gremlin/structure/util/ElementHelper.java#L62
> but perhaps it is time to treat this issue as a first class citizen as part 
> of the Graph API.  I think that some vendors might actually be able to 
> optimize this function as well.  
> Another aspect of "getOrCreate" is "upsert" as well as options to ensure 
> uniqueness.  All of these things we've at some point or another built 
> variations of outside of TinkerPop for applications, data loading, etc.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to