use of org.locationtech.geogig.api.RevTree in project GeoGig by boundlessgeo.
the class WriteBack method getTreeChild.
private Optional<NodeRef> getTreeChild(RevTreeBuilder parent, String childPath) {
RevTree realParent = parent.build();
FindTreeChild cmd = command(FindTreeChild.class).setIndex(true).setParent(realParent).setChildPath(childPath);
Optional<NodeRef> nodeRef = cmd.call();
return nodeRef;
}
use of org.locationtech.geogig.api.RevTree in project GeoGig by boundlessgeo.
the class WriteBack method writeBack.
private ObjectId writeBack(RevTreeBuilder ancestor, final String ancestorPath, final RevTree childTree, final String childPath, final ObjectDatabase targetDatabase, final ObjectId metadataId) {
final ObjectId treeId = childTree.getId();
targetDatabase.put(childTree);
final boolean isDirectChild = NodeRef.isDirectChild(ancestorPath, childPath);
if (isDirectChild) {
Envelope treeBounds = null;
if (!metadataId.isNull()) {
// only include bounds for trees with a default feature type
treeBounds = SpatialOps.boundsOf(childTree);
}
String childName = childPath;
Node treeNode = Node.create(childName, treeId, metadataId, TYPE.TREE, treeBounds);
ancestor.put(treeNode);
RevTree newAncestor = ancestor.build();
targetDatabase.put(newAncestor);
return newAncestor.getId();
}
final String parentPath = NodeRef.parentPath(childPath);
Optional<NodeRef> parentRef = getTreeChild(ancestor, parentPath);
RevTreeBuilder parentBuilder;
ObjectId parentMetadataId = ObjectId.NULL;
if (parentRef.isPresent()) {
ObjectId parentId = parentRef.get().objectId();
parentMetadataId = parentRef.get().getMetadataId();
parentBuilder = getTree(parentId, targetDatabase).builder(targetDatabase);
} else {
parentBuilder = RevTree.EMPTY.builder(targetDatabase);
}
String childName = NodeRef.nodeFromPath(childPath);
Envelope treeBounds = null;
if (!metadataId.isNull()) {
// only include bounds for trees with a default feature type
treeBounds = SpatialOps.boundsOf(childTree);
}
Node treeNode = Node.create(childName, treeId, metadataId, TYPE.TREE, treeBounds);
parentBuilder.put(treeNode);
RevTree parent = parentBuilder.build();
return writeBack(ancestor, ancestorPath, parent, parentPath, targetDatabase, parentMetadataId);
}
use of org.locationtech.geogig.api.RevTree in project GeoGig by boundlessgeo.
the class WriteTree method resolveTargetTree.
private RevTreeBuilder resolveTargetTree(final RevTree root, String treePath, Map<String, RevTreeBuilder> treeCache, Map<String, ObjectId> metadataCache, ObjectId fallbackMetadataId, ObjectDatabase repositoryDatabase) {
RevTreeBuilder treeBuilder = treeCache.get(treePath);
if (treeBuilder == null) {
if (NodeRef.ROOT.equals(treePath)) {
treeBuilder = root.builder(repositoryDatabase);
} else {
Optional<NodeRef> treeRef = command(FindTreeChild.class).setIndex(false).setParent(root).setChildPath(treePath).call();
if (treeRef.isPresent()) {
metadataCache.put(treePath, treeRef.get().getMetadataId());
treeBuilder = command(RevObjectParse.class).setObjectId(treeRef.get().objectId()).call(RevTree.class).get().builder(repositoryDatabase);
} else {
metadataCache.put(treePath, fallbackMetadataId);
treeBuilder = new RevTreeBuilder(repositoryDatabase);
}
}
treeCache.put(treePath, treeBuilder);
}
return treeBuilder;
}
use of org.locationtech.geogig.api.RevTree in project GeoGig by boundlessgeo.
the class WriteTree method _call.
/**
* Executes the write tree operation.
*
* @return the new root tree id, the current HEAD tree id if there are no differences between
* the index and the HEAD, or {@code null} if the operation has been cancelled (as
* indicated by the {@link #getProgressListener() progress listener}.
*/
@Override
protected ObjectId _call() {
final ProgressListener progress = getProgressListener();
final RevTree oldRootTree = resolveRootTree();
final ObjectDatabase repositoryDatabase = objectDatabase();
Iterator<DiffEntry> diffs = null;
long numChanges = 0;
if (diffSupplier == null) {
diffs = index().getStaged(pathFilters);
numChanges = index().countStaged(pathFilters).count();
} else {
diffs = diffSupplier.get();
}
if (!diffs.hasNext()) {
return oldRootTree.getId();
}
if (progress.isCanceled()) {
return null;
}
Map<String, RevTreeBuilder> repositoryChangedTrees = Maps.newHashMap();
Map<String, NodeRef> indexChangedTrees = Maps.newHashMap();
Map<String, ObjectId> changedTreesMetadataId = Maps.newHashMap();
Set<String> deletedTrees = Sets.newHashSet();
final boolean moveObjects = this.moveObjects;
NodeRef ref;
int i = 0;
RevTree stageHead = index().getTree();
while (diffs.hasNext()) {
if (numChanges != 0) {
progress.setProgress((float) (++i * 100) / numChanges);
}
if (progress.isCanceled()) {
return null;
}
DiffEntry diff = diffs.next();
// ignore the root entry
if (NodeRef.ROOT.equals(diff.newName()) || NodeRef.ROOT.equals(diff.oldName())) {
continue;
}
ref = diff.getNewObject();
if (ref == null) {
ref = diff.getOldObject();
}
final String parentPath = ref.getParentPath();
final boolean isDelete = ChangeType.REMOVED.equals(diff.changeType());
final TYPE type = ref.getType();
if (isDelete && deletedTrees.contains(parentPath)) {
// tree delete entry was processed
continue;
}
RevTreeBuilder parentTree = resolveTargetTree(oldRootTree, parentPath, repositoryChangedTrees, changedTreesMetadataId, ObjectId.NULL, repositoryDatabase);
if (type == TYPE.TREE && !isDelete) {
// cache the tree
resolveTargetTree(oldRootTree, ref.name(), repositoryChangedTrees, changedTreesMetadataId, ref.getMetadataId(), repositoryDatabase);
}
resolveSourceTreeRef(parentPath, indexChangedTrees, changedTreesMetadataId, stageHead);
Preconditions.checkState(parentTree != null);
if (isDelete) {
String oldName = diff.getOldObject().getNode().getName();
parentTree.remove(oldName);
if (TYPE.TREE.equals(type)) {
deletedTrees.add(ref.path());
}
} else {
if (moveObjects && ref.getType().equals(TYPE.TREE)) {
RevTree tree = stagingDatabase().getTree(ref.objectId());
if (!ref.getMetadataId().isNull()) {
repositoryDatabase.put(stagingDatabase().getFeatureType(ref.getMetadataId()));
}
if (tree.isEmpty()) {
repositoryDatabase.put(tree);
} else {
continue;
}
} else if (moveObjects) {
deepMove(ref.getNode());
}
parentTree.put(ref.getNode());
}
}
if (progress.isCanceled()) {
return null;
}
// now write back all changed trees
ObjectId newTargetRootId = oldRootTree.getId();
RevTreeBuilder directRootEntries = repositoryChangedTrees.remove(NodeRef.ROOT);
if (directRootEntries != null) {
RevTree newRoot = directRootEntries.build();
repositoryDatabase.put(newRoot);
newTargetRootId = newRoot.getId();
}
for (Map.Entry<String, RevTreeBuilder> e : repositoryChangedTrees.entrySet()) {
String treePath = e.getKey();
ObjectId metadataId = changedTreesMetadataId.get(treePath);
RevTreeBuilder treeBuilder = e.getValue();
RevTree newRoot = getTree(newTargetRootId);
RevTree tree = treeBuilder.build();
newTargetRootId = writeBack(newRoot.builder(repositoryDatabase), tree, treePath, metadataId);
}
progress.complete();
return newTargetRootId;
}
use of org.locationtech.geogig.api.RevTree in project GeoGig by boundlessgeo.
the class WriteTree2 method handleDeletedTrees.
private void handleDeletedTrees(TreeDifference treeDifference, Set<String> ignoreList) {
SortedSet<NodeRef> deletes = treeDifference.findDeletes();
for (NodeRef ref : deletes) {
String path = ref.path();
if (ignoreList.contains(path)) {
continue;
}
ignoreList.add(path);
if (!filterMatchesOrIsParent(path)) {
if (filterApplies(path, treeDifference.getRightTree())) {
// can't optimize
RevTree newTree = applyChanges(ref, null);
Node newNode = Node.tree(ref.name(), newTree.getId(), ref.getMetadataId());
MutableTree leftTree = treeDifference.getLeftTree();
leftTree.forceChild(ref.getParentPath(), newNode);
}
} else {
MutableTree leftTree = treeDifference.getLeftTree();
leftTree.removeChild(path);
}
}
}
Aggregations