Traversal.java
/*
* Copyright © 2014 - 2021 Leipzig University (Database Research Group)
*
* 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.gradoop.flink.representation.transactional.traversalcode;
import java.io.Serializable;
/**
* DFSStep of an embedding.
*
* @param <C> vertex and edge value type
*/
public class Traversal<C extends Comparable<C>>
implements Serializable, Comparable<Traversal<C>> {
/**
* separator between vertex time and label
*/
private static final char TIME_LABEL_SEPARATOR = ':';
/**
* outgoing edge start
*/
private static final char OUTGOING_CHAR = '>';
/**
* incoming edge start
*/
private static final char INCOMING_CHAR = '<';
/**
* edge start of undirected and end of all edges
*/
private static final char EDGE_CHAR = '-';
/**
* extension start time
*/
private final int fromTime;
/**
* extension start label
*/
private final C fromValue;
/**
* outgoing or incoming traversal
*/
private final boolean outgoing;
/**
* edge label
*/
private final C edgeValue;
/**
* traversal end time
*/
private final int toTime;
/**
* traversal end label
*/
private final C toValue;
/**
* Constructor
* @param fromTime extension start time
* @param fromValue extension start label
* @param outgoing outgoing or incoming traversal
* @param edgeValue edge label
* @param toTime traversal end time
* @param toValue traversal end label
*/
public Traversal(
int fromTime, C fromValue, boolean outgoing, C edgeValue, int toTime, C toValue) {
this.fromTime = fromTime;
this.fromValue = fromValue;
this.outgoing = outgoing;
this.edgeValue = edgeValue;
this.toTime = toTime;
this.toValue = toValue;
}
public boolean isBackwards() {
return toTime <= fromTime;
}
public boolean isLoop() {
return fromTime == toTime;
}
public int getFromTime() {
return fromTime;
}
public C getFromValue() {
return fromValue;
}
public boolean isOutgoing() {
return outgoing;
}
public C getEdgeValue() {
return edgeValue;
}
public int getToTime() {
return toTime;
}
public C getToValue() {
return toValue;
}
@Override
public String toString() {
return String.valueOf(fromTime) + TIME_LABEL_SEPARATOR + fromValue +
(outgoing ? OUTGOING_CHAR : INCOMING_CHAR) + edgeValue + EDGE_CHAR +
toTime + TIME_LABEL_SEPARATOR + toValue;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Traversal<?> that = (Traversal<?>) o;
if (fromTime != that.fromTime) {
return false;
}
if (outgoing != that.outgoing) {
return false;
}
if (toTime != that.toTime) {
return false;
}
if (!fromValue.equals(that.fromValue)) {
return false;
}
if (!edgeValue.equals(that.edgeValue)) {
return false;
}
return toValue.equals(that.toValue);
}
@Override
public int hashCode() {
int result = fromTime;
result = 31 * result + fromValue.hashCode();
result = 31 * result + (outgoing ? 1 : 0);
result = 31 * result + edgeValue.hashCode();
result = 31 * result + toTime;
result = 31 * result + toValue.hashCode();
return result;
}
/**
* Comparison according to gSpan lexicographic order.
*
* @param that other extension
* @return comparison result
*/
@Override
public int compareTo(Traversal<C> that) {
int comparison;
// no difference is times
if (this.fromTime == that.fromTime && this.toTime == that.toTime) {
// compare from values
comparison = this.fromValue.compareTo(that.fromValue);
if (comparison == 0) {
// compare direction
boolean thisIsOutgoing = this.isOutgoing();
boolean thatIsOutgoing = that.isOutgoing();
if (thisIsOutgoing && !thatIsOutgoing) {
comparison = -1;
} else if (thatIsOutgoing && !thisIsOutgoing) {
comparison = 1;
} else {
// compare edge values
comparison = this.edgeValue.compareTo(that.edgeValue);
if (comparison == 0) {
// compare to values
comparison = this.toValue.compareTo(that.toValue);
}
}
}
// time differences
} else {
// compare backtracking
boolean thisIsBacktrack = this.isBackwards();
boolean thatIsBacktrack = that.isBackwards();
if (thisIsBacktrack && !thatIsBacktrack) {
comparison = -1;
} else if (thatIsBacktrack && !thisIsBacktrack) {
comparison = 1;
} else {
// both forwards
if (thatIsBacktrack) {
// back to earlier vertex is smaller
comparison = this.toTime - that.toTime;
// both backwards
} else {
// forwards from later vertex is smaller
comparison = that.fromTime - this.fromTime;
}
}
}
return comparison;
}
public boolean isForwards() {
return !isBackwards();
}
}