use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class TreeDifference method findPureMetadataChanges.
/**
* Finds tree pointers that point to the same tree (path and object id) on the left and right
* sides of the comparison but have different {@link NodeRef#getMetadataId() metadata ids}
*/
public Map<NodeRef, NodeRef> findPureMetadataChanges() {
SortedMap<String, MutableTree> leftEntries = leftTree.getChildrenAsMap();
SortedMap<String, MutableTree> rightEntries = rightTree.getChildrenAsMap();
Map<NodeRef, NodeRef> matches = Maps.newTreeMap();
for (Map.Entry<String, MutableTree> e : leftEntries.entrySet()) {
final String nodePath = e.getKey();
final MutableTree leftTree = e.getValue();
final Node leftNode = leftTree.getNode();
@Nullable final MutableTree rightTree = rightEntries.get(nodePath);
final Node rightNode = rightTree == null ? null : rightTree.getNode();
if (leftNode.equals(rightNode)) {
final Optional<ObjectId> leftMetadata = leftNode.getMetadataId();
final Optional<ObjectId> rightMetadata = rightNode.getMetadataId();
if (!leftMetadata.equals(rightMetadata)) {
String parentPath = NodeRef.parentPath(nodePath);
NodeRef leftRef = new NodeRef(leftNode, parentPath, ObjectId.NULL);
NodeRef rightRef = new NodeRef(rightNode, parentPath, ObjectId.NULL);
matches.put(leftRef, rightRef);
}
}
}
return matches;
}
use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class WriteTree2 method handleRemainingDifferences.
private void handleRemainingDifferences(TreeDifference treeDifference, Set<String> ignoreList) {
// old/new refs to trees that have changed and apply to the pathFilters, deepest paths first
final SortedMap<NodeRef, NodeRef> changedTrees = treeDifference.findChanges();
// filterChanges(changedTrees);
final SortedMap<NodeRef, NodeRef> filteredChangedTrees = changedTrees;
for (Map.Entry<NodeRef, NodeRef> changedTreeRefs : filteredChangedTrees.entrySet()) {
NodeRef leftTreeRef = changedTreeRefs.getKey();
NodeRef rightTreeRef = changedTreeRefs.getValue();
String newPath = rightTreeRef.path();
if (ignoreList.contains(newPath)) {
continue;
}
if (!filterApplies(newPath, treeDifference.getRightTree())) {
continue;
}
ignoreList.add(newPath);
RevTree tree = applyChanges(leftTreeRef, rightTreeRef);
Envelope bounds = SpatialOps.boundsOf(tree);
Node newTreeNode = Node.create(rightTreeRef.name(), tree.getId(), rightTreeRef.getMetadataId(), TYPE.TREE, bounds);
MutableTree leftRoot = treeDifference.getLeftTree();
String parentPath = rightTreeRef.getParentPath();
leftRoot.setChild(parentPath, newTreeNode);
}
}
use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class WriteTree2 method applyChanges.
private RevTree applyChanges(@Nullable final NodeRef leftTreeRef, @Nullable final NodeRef rightTreeRef) {
Preconditions.checkArgument(leftTreeRef != null || rightTreeRef != null, "either left or right tree shall be non null");
final ObjectDatabase repositoryDatabase = objectDatabase();
final String treePath = rightTreeRef == null ? leftTreeRef.path() : rightTreeRef.path();
final List<String> strippedPathFilters = stripParentAndFiltersThatDontApply(this.pathFilters, treePath);
// find the diffs that apply to the path filters
final ObjectId leftTreeId = leftTreeRef == null ? RevTree.EMPTY_TREE_ID : leftTreeRef.objectId();
final ObjectId rightTreeId = rightTreeRef == null ? RevTree.EMPTY_TREE_ID : rightTreeRef.objectId();
final Predicate<Bounded> existsFilter = new Predicate<Bounded>() {
private final ObjectDatabase targetDb = repositoryDatabase;
@Override
public boolean apply(Bounded input) {
ObjectId id = null;
if (input instanceof Node && TYPE.TREE.equals(((Node) input).getType())) {
id = ((Node) input).getObjectId();
} else if (input instanceof Bucket) {
Bucket b = (Bucket) input;
id = b.id();
}
if (id != null) {
if (targetDb.exists(id)) {
LOGGER.trace("Ignoring {}. Already exists in target database.", input);
return false;
}
}
return true;
}
};
DiffTree diffs = command(DiffTree.class).setRecursive(false).setReportTrees(false).setOldTree(leftTreeId).setNewTree(rightTreeId).setPathFilter(strippedPathFilters).setCustomFilter(existsFilter);
// move new blobs from the index to the repository (note: this could be parallelized)
Supplier<Iterator<Node>> nodesToMove = asNodeSupplierOfNewContents(diffs, strippedPathFilters);
command(DeepMove.class).setObjects(nodesToMove).call();
final StagingDatabase stagingDatabase = stagingDatabase();
final RevTree currentLeftTree = stagingDatabase.getTree(leftTreeId);
final RevTreeBuilder builder = currentLeftTree.builder(repositoryDatabase);
// remove the exists filter, we need to create the new trees taking into account all the
// nodes
diffs.setCustomFilter(null);
Iterator<DiffEntry> iterator = diffs.get();
if (!strippedPathFilters.isEmpty()) {
final Set<String> expected = Sets.newHashSet(strippedPathFilters);
iterator = Iterators.filter(iterator, new Predicate<DiffEntry>() {
@Override
public boolean apply(DiffEntry input) {
boolean applies;
if (input.isDelete()) {
applies = expected.contains(input.oldName());
} else {
applies = expected.contains(input.newName());
}
return applies;
}
});
}
for (; iterator.hasNext(); ) {
final DiffEntry diff = iterator.next();
if (diff.isDelete()) {
builder.remove(diff.oldName());
} else {
NodeRef newObject = diff.getNewObject();
Node node = newObject.getNode();
builder.put(node);
}
}
final RevTree newTree = builder.build();
repositoryDatabase.put(newTree);
return newTree;
}
use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class WriteTree2 method handleRenames.
/**
* A renamed tree is recognized by checking if a tree on the right points to the same object
* that a tree on the left that doesn't exist anymore on the right.
* <p>
* Left entries are the original ones, and right entries are the new ones.
* </p>
*
* @param treeDifference
* @param ignoreList
*/
private void handleRenames(TreeDifference treeDifference, Set<String> ignoreList) {
final SortedMap<NodeRef, NodeRef> renames = treeDifference.findRenames();
for (Map.Entry<NodeRef, NodeRef> e : renames.entrySet()) {
NodeRef oldValue = e.getKey();
NodeRef newValue = e.getValue();
String newPath = newValue.path();
if (ignoreList.contains(newPath)) {
continue;
}
ignoreList.add(newPath);
if (!filterMatchesOrIsParent(newPath)) {
// filter doesn't apply to the renamed tree as a whole
continue;
}
LOGGER.trace("Handling rename of {} as {}", oldValue.path(), newPath);
MutableTree leftTree = treeDifference.getLeftTree();
leftTree.removeChild(oldValue.path());
leftTree.setChild(newValue.getParentPath(), newValue.getNode());
}
}
use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class WriteTree2 method computeTreeDifference.
private TreeDifference computeTreeDifference() {
final String rightTreeish = Ref.STAGE_HEAD;
final ObjectId rootTreeId = resolveRootTreeId();
final ObjectId stageRootId = index().getTree().getId();
final Supplier<Iterator<NodeRef>> leftTreeRefs;
final Supplier<Iterator<NodeRef>> rightTreeRefs;
if (rootTreeId.isNull()) {
Iterator<NodeRef> empty = Iterators.emptyIterator();
leftTreeRefs = Suppliers.ofInstance(empty);
} else {
leftTreeRefs = command(LsTreeOp.class).setReference(rootTreeId.toString()).setStrategy(Strategy.DEPTHFIRST_ONLY_TREES);
}
rightTreeRefs = command(LsTreeOp.class).setReference(rightTreeish).setStrategy(Strategy.DEPTHFIRST_ONLY_TREES);
MutableTree leftTree = MutableTree.createFromRefs(rootTreeId, leftTreeRefs);
MutableTree rightTree = MutableTree.createFromRefs(stageRootId, rightTreeRefs);
TreeDifference treeDifference = TreeDifference.create(leftTree, rightTree);
return treeDifference;
}
Aggregations