// Copyright 2017 JanusGraph Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.janusgraph.core;
import com.google.common.base.Preconditions;
import org.apache.tinkerpop.gremlin.structure.Direction;
/**
* The multiplicity of edges between vertices for a given label. Multiplicity here is understood in the same sense as
* for UML class diagrams {@url http://en.wikipedia.org/wiki/Class_diagram#Multiplicity}
*
* @author Matthias Broecheler (me@matthiasb.com)
*/
public enum Multiplicity {
/**
* The given edge label specifies a multi-graph, meaning that the multiplicity is not constrained and that
* there may be multiple edges of this label between any given pair of vertices.
*
* @link http://en.wikipedia.org/wiki/Multigraph
*/
MULTI,
/**
* The given edge label specifies a simple graph, meaning that the multiplicity is not constrained but that there
* can only be at most a single edge of this label between a given pair of vertices.
*/
SIMPLE,
/**
* There can only be a single in-edge of this label for a given vertex but multiple out-edges (i.e. in-unique)
*/
ONE2MANY,
/**
* There can only be a single out-edge of this label for a given vertex but multiple in-edges (i.e. out-unique)
*/
MANY2ONE,
/**
* There can be only a single in and out-edge of this label for a given vertex (i.e. unique in both directions).
*/
ONE2ONE;
/**
* Whether this multiplicity imposes any constraint on the number of edges that may exist between a pair of vertices.
*
* @return
*/
public boolean isConstrained() {
return this!=MULTI;
}
public boolean isConstrained(Direction direction) {
if (direction==Direction.BOTH) return isConstrained();
if (this==MULTI) return false;
if (this==SIMPLE) return true;
return isUnique(direction);
}
/**
* If this multiplicity implies edge uniqueness in the given direction for any given vertex.
*
* @param direction
* @return
*/
public boolean isUnique(Direction direction) {
switch (direction) {
case IN:
return this==ONE2MANY || this==ONE2ONE;
case OUT:
return this==MANY2ONE || this==ONE2ONE;
case BOTH:
return this==ONE2ONE;
default: throw new AssertionError("Unknown direction: " + direction);
}
}
//######### CONVERTING MULTIPLICITY <-> CARDINALITY ########
public static Multiplicity convert(Cardinality cardinality) {
Preconditions.checkNotNull(cardinality);
switch(cardinality) {
case LIST: return MULTI;
case SET: return SIMPLE;
case SINGLE: return MANY2ONE;
default: throw new AssertionError("Unknown cardinality: " + cardinality);
}
}
public Cardinality getCardinality() {
switch (this) {
case MULTI: return Cardinality.LIST;
case SIMPLE: return Cardinality.SET;
case MANY2ONE: return Cardinality.SINGLE;
default: throw new AssertionError("Invalid multiplicity: " + this);
}
}
}