tikhomirov@648: /* tikhomirov@648: * Copyright (c) 2013 TMate Software Ltd tikhomirov@648: * tikhomirov@648: * This program is free software; you can redistribute it and/or modify tikhomirov@648: * it under the terms of the GNU General Public License as published by tikhomirov@648: * the Free Software Foundation; version 2 of the License. tikhomirov@648: * tikhomirov@648: * This program is distributed in the hope that it will be useful, tikhomirov@648: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@648: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@648: * GNU General Public License for more details. tikhomirov@648: * tikhomirov@648: * For information on how to redistribute this software under tikhomirov@648: * the terms of a license other than GNU General Public License tikhomirov@648: * contact TMate Software at support@hg4j.com tikhomirov@648: */ tikhomirov@648: package org.tmatesoft.hg.internal; tikhomirov@648: tikhomirov@648: import java.util.Collection; tikhomirov@648: import java.util.Collections; tikhomirov@648: import java.util.HashSet; tikhomirov@648: import java.util.Set; tikhomirov@648: tikhomirov@648: import org.tmatesoft.hg.core.Nodeid; tikhomirov@648: tikhomirov@648: /** tikhomirov@648: * Unmodifiable collection of revisions with handy set operations tikhomirov@648: * tikhomirov@648: * @author Artem Tikhomirov tikhomirov@648: * @author TMate Software Ltd. tikhomirov@648: */ tikhomirov@648: public final class RevisionSet { tikhomirov@648: tikhomirov@648: private final Set elements; tikhomirov@648: tikhomirov@648: public RevisionSet(Collection revisions) { tikhomirov@648: this(revisions == null ? new HashSet() : new HashSet(revisions)); tikhomirov@648: } tikhomirov@648: tikhomirov@648: private RevisionSet(HashSet revisions) { tikhomirov@648: if (revisions.isEmpty()) { tikhomirov@648: elements = Collections.emptySet(); tikhomirov@648: } else { tikhomirov@648: elements = revisions; tikhomirov@648: } tikhomirov@648: } tikhomirov@648: tikhomirov@648: public RevisionSet roots() { tikhomirov@648: throw Internals.notImplemented(); tikhomirov@648: } tikhomirov@648: tikhomirov@648: public RevisionSet heads() { tikhomirov@648: throw Internals.notImplemented(); tikhomirov@648: } tikhomirov@648: tikhomirov@648: public RevisionSet intersect(RevisionSet other) { tikhomirov@648: if (isEmpty()) { tikhomirov@648: return this; tikhomirov@648: } tikhomirov@648: if (other.isEmpty()) { tikhomirov@648: return other; tikhomirov@648: } tikhomirov@648: HashSet copy = new HashSet(elements); tikhomirov@648: copy.retainAll(other.elements); tikhomirov@648: return copy.size() == elements.size() ? this : new RevisionSet(copy); tikhomirov@648: } tikhomirov@648: tikhomirov@648: public RevisionSet subtract(RevisionSet other) { tikhomirov@648: if (isEmpty() || other.isEmpty()) { tikhomirov@648: return this; tikhomirov@648: } tikhomirov@648: HashSet copy = new HashSet(elements); tikhomirov@648: copy.removeAll(other.elements); tikhomirov@648: return copy.size() == elements.size() ? this : new RevisionSet(copy); tikhomirov@648: } tikhomirov@648: tikhomirov@648: public RevisionSet union(RevisionSet other) { tikhomirov@648: if (isEmpty()) { tikhomirov@648: return other; tikhomirov@648: } tikhomirov@648: if (other.isEmpty()) { tikhomirov@648: return this; tikhomirov@648: } tikhomirov@648: HashSet copy = new HashSet(elements); tikhomirov@648: copy.addAll(other.elements); tikhomirov@648: return new RevisionSet(copy); tikhomirov@648: } tikhomirov@648: tikhomirov@648: /** tikhomirov@648: * A ^ B := (A\B).union(B\A) tikhomirov@648: * A ^ B := A.union(B) \ A.intersect(B) tikhomirov@648: */ tikhomirov@648: public RevisionSet symmetricDifference(RevisionSet other) { tikhomirov@648: if (isEmpty()) { tikhomirov@648: return this; tikhomirov@648: } tikhomirov@648: if (other.isEmpty()) { tikhomirov@648: return other; tikhomirov@648: } tikhomirov@648: HashSet copyA = new HashSet(elements); tikhomirov@648: HashSet copyB = new HashSet(other.elements); tikhomirov@648: copyA.removeAll(other.elements); tikhomirov@648: copyB.removeAll(elements); tikhomirov@648: copyA.addAll(copyB); tikhomirov@648: return new RevisionSet(copyA); tikhomirov@648: } tikhomirov@648: tikhomirov@648: public boolean isEmpty() { tikhomirov@648: return elements.isEmpty(); tikhomirov@648: } tikhomirov@648: tikhomirov@648: @Override tikhomirov@648: public String toString() { tikhomirov@648: StringBuilder sb = new StringBuilder(); tikhomirov@648: sb.append('<'); tikhomirov@648: if (!isEmpty()) { tikhomirov@648: sb.append(elements.size()); tikhomirov@648: sb.append(':'); tikhomirov@648: } tikhomirov@648: for (Nodeid n : elements) { tikhomirov@648: sb.append(n.shortNotation()); tikhomirov@648: sb.append(','); tikhomirov@648: } tikhomirov@648: if (sb.length() > 1) { tikhomirov@648: sb.setCharAt(sb.length() - 1, '>'); tikhomirov@648: } else { tikhomirov@648: sb.append('>'); tikhomirov@648: } tikhomirov@648: return sb.toString(); tikhomirov@648: } tikhomirov@648: tikhomirov@648: @Override tikhomirov@648: public boolean equals(Object obj) { tikhomirov@648: if (false == obj instanceof RevisionSet) { tikhomirov@648: return false; tikhomirov@648: } tikhomirov@648: return elements.equals(((RevisionSet) obj).elements); tikhomirov@648: } tikhomirov@648: tikhomirov@648: @Override tikhomirov@648: public int hashCode() { tikhomirov@648: return elements.hashCode(); tikhomirov@648: } tikhomirov@648: }