blob: 7625dede96c8134aca6f4423e1b3f9d1d786c8b6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 VMware Inc.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* SpringSource, a division of VMware - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.equinox.internal.region;
import org.eclipse.equinox.region.Region;
import org.eclipse.equinox.region.RegionDigraphVisitor;
import org.eclipse.equinox.region.RegionDigraph.FilteredRegion;
import java.util.HashSet;
import java.util.Set;
/**
* {@link SubgraphTraverser} is a utility for traversing a subgraph of a {@link RegionDigraph} calling a
* {@link RegionDigraphVisitor} on the way.
* <p />
*
* <strong>Concurrent Semantics</strong><br />
* Thread safe.
*/
final class SubgraphTraverser {
void visitSubgraph(Region startingRegion, RegionDigraphVisitor visitor) {
visitRemainingSubgraph(startingRegion, visitor, new HashSet<Region>());
}
private void visitRemainingSubgraph(Region r, RegionDigraphVisitor visitor, Set<Region> path) {
if (!path.contains(r)) {
if (visitor.visit(r)) {
traverseEdges(r, visitor, path);
}
}
}
private void traverseEdges(Region r, RegionDigraphVisitor visitor, Set<Region> path) {
for (FilteredRegion fr : r.getEdges()) {
if (visitor.preEdgeTraverse(fr.getFilter())) {
try {
visitRemainingSubgraph(fr.getRegion(), visitor, extendPath(r, path));
} finally {
visitor.postEdgeTraverse(fr.getFilter());
}
}
}
}
private Set<Region> extendPath(Region r, Set<Region> path) {
Set<Region> newPath = new HashSet<Region>(path);
newPath.add(r);
return newPath;
}
}