/* Copyright (c) 2014 Boundless and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Distribution License v1.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/org/documents/edl-v10.html * * Contributors: * Justin Deoliveira (Boundless) - initial implementation */ package org.locationtech.geogig.storage.sqlite; import java.util.Iterator; import java.util.List; import java.util.Queue; import java.util.Set; import org.locationtech.geogig.api.ObjectId; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** * Walks a path from the specified node to a root, bifurcating along the way in cases where a node * has multiple parents. * * @author Justin Deoliveira, Boundless * * @param <C> Connection type. */ public class PathToRootWalker<T> implements Iterator<List<ObjectId>> { SQLiteGraphDatabase<T> graph; T cx; Queue<ObjectId> q; Set<ObjectId> seen; public PathToRootWalker(ObjectId start, SQLiteGraphDatabase<T> graph, T cx) { this.graph = graph; this.cx = cx; q = Lists.newLinkedList(); q.add(start); seen = Sets.newHashSet(); } @Override public boolean hasNext() { return !q.isEmpty(); } @Override public List<ObjectId> next() { List<ObjectId> curr = Lists.newArrayList(); List<ObjectId> next = Lists.newArrayList(); while (!q.isEmpty()) { ObjectId node = q.poll(); curr.add(node); Iterables.addAll(next, Iterables.transform(graph.outgoing(node.toString(), cx), StringToObjectId.INSTANCE)); } seen.addAll(curr); q.addAll(next); return curr; } public boolean seen(ObjectId node) { return seen.contains(node); } @Override public void remove() { throw new UnsupportedOperationException(); } }