/* 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: * Gabriel Roldan (Boundless) - initial implementation */ package org.locationtech.geogig.api.plumbing.diff; import org.locationtech.geogig.api.Bucket; import org.locationtech.geogig.api.Node; import org.locationtech.geogig.api.NodeRef; import org.locationtech.geogig.api.ObjectId; import org.locationtech.geogig.api.RevTree; import org.locationtech.geogig.api.plumbing.diff.PreOrderDiffWalk.Consumer; import org.locationtech.geogig.storage.ObjectDatabase; /** * A {@link Consumer} for diffs that computes the number for tree and feature changes between the * traversal's two trees. * * <p> * Use {@link DiffCountConsumer#get() consumer.get()} after {@link PreOrderDiffWalk#walk(Consumer) * visitor.walk(consumer)} to get the resulting {@link DiffObjectCount}. */ public class DiffCountConsumer implements PreOrderDiffWalk.Consumer { private ObjectDatabase db; private DiffObjectCount count = new DiffObjectCount(); public DiffCountConsumer(ObjectDatabase db) { this.db = db; } public DiffObjectCount get() { return count; } @Override public void feature(Node left, Node right) { if (left == null) { count.addedFeatures(1L); } else if (right == null) { count.removedFeatures(1L); } else { count.changedFeatures(1L); } } @Override public boolean tree(Node left, Node right) { final Node node = left == null ? right : left; if (NodeRef.ROOT.equals(node.getName())) { // ignore the call on the root tree and follow the traversal return true; } if (left == null || right == null) { addTreeFeatures(node.getObjectId(), left != null, right != null); if (left == null) { count.addedTrees(1); } else { count.removedTrees(1); } return false; } count.changedTrees(1);// the tree changed, or this method wouldn't have been called return true; } @Override public boolean bucket(int bucketIndex, int bucketDepth, Bucket left, Bucket right) { if (left == null || right == null) { Bucket bucket = left == null ? right : left; addTreeFeatures(bucket.id(), left != null, right != null); return false; } return true; } private boolean addTreeFeatures(ObjectId treeId, boolean leftPresent, boolean rightPresent) { RevTree tree = db.getTree(treeId); long size = tree.size(); if (leftPresent && rightPresent) { count.changedFeatures(size); } else if (leftPresent) { count.removedFeatures(size); } else { count.addedFeatures(size); } int numTrees = tree.numTrees(); return numTrees > 0; } @Override public void endTree(Node left, Node right) { // no need to do anything } @Override public void endBucket(int bucketIndex, int bucketDepth, Bucket left, Bucket right) { // no need to do anything } }