use of org.locationtech.geogig.api.Node in project GeoGig by boundlessgeo.
the class PreOrderDiffWalkTest method testLeafLeafTwoRemoves.
@Test
public void testLeafLeafTwoRemoves() {
// two leaf trees
RevTree left = createFeaturesTree(leftSource, "f", 5).build();
RevTree right = createFeaturesTree(rightSource, "f", 3).build();
PreOrderDiffWalk visitor = new PreOrderDiffWalk(left, right, leftSource, rightSource);
final Node lroot = nodeFor(left);
final Node rroot = nodeFor(right);
when(consumer.tree(eq(lroot), eq(rroot))).thenReturn(true);
visitor.walk(consumer);
verify(consumer, times(1)).tree(eq(lroot), eq(rroot));
ArgumentCaptor<Node> larg = ArgumentCaptor.forClass(Node.class);
ArgumentCaptor<Node> rarg = ArgumentCaptor.forClass(Node.class);
verify(consumer, times(2)).feature(larg.capture(), rarg.capture());
assertEquals(2, larg.getAllValues().size());
assertNull(rarg.getAllValues().get(0));
assertNull(rarg.getAllValues().get(1));
// the two added nodes
Node n1 = featureNode("f", 3);
Node n2 = featureNode("f", 4);
assertTrue(larg.getAllValues().contains(n1));
assertTrue(larg.getAllValues().contains(n2));
verify(consumer, times(1)).endTree(eq(lroot), eq(rroot));
verifyNoMoreInteractions(consumer);
}
use of org.locationtech.geogig.api.Node in project GeoGig by boundlessgeo.
the class PreOrderDiffWalkTest method testSkipBucket.
@Test
public void testSkipBucket() {
// two bucket trees of depth 2
final int size = RevTree.MAX_BUCKETS * RevTree.NORMALIZED_SIZE_LIMIT;
RevTree left = createFeaturesTree(leftSource, "f", size).build();
// all features
RevTree right = createFeaturesTree(rightSource, "f", size, 0, true).build();
// changed
assertDepth(left, leftSource, 2);
assertDepth(right, rightSource, 2);
PreOrderDiffWalk visitor = new PreOrderDiffWalk(left, right, leftSource, rightSource);
final Node lroot = nodeFor(left);
final Node rroot = nodeFor(right);
// consume the root tree
when(consumer.tree(eq(lroot), eq(rroot))).thenReturn(true);
// skip all buckets of depth 0
when(consumer.bucket(anyInt(), eq(0), any(Bucket.class), any(Bucket.class))).thenReturn(false);
visitor.walk(consumer);
verify(consumer, times(1)).tree(eq(lroot), eq(rroot));
verify(consumer, times(32)).bucket(anyInt(), eq(0), any(Bucket.class), any(Bucket.class));
// should not be any call to consumer.features as we skipped all buckets of depth 0 (which
// point to leaf trees)
verify(consumer, times(0)).feature(any(Node.class), any(Node.class));
verify(consumer, times(32)).endBucket(anyInt(), eq(0), any(Bucket.class), any(Bucket.class));
verify(consumer, times(1)).endTree(eq(lroot), eq(rroot));
verifyNoMoreInteractions(consumer);
}
use of org.locationtech.geogig.api.Node in project GeoGig by boundlessgeo.
the class GeogigFeatureStore method addFeatures.
@Override
public final List<FeatureId> addFeatures(FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection) throws IOException {
if (Transaction.AUTO_COMMIT.equals(getTransaction())) {
throw new UnsupportedOperationException("GeoGIG does not support AUTO_COMMIT");
}
Preconditions.checkState(getDataStore().isAllowTransactions(), "Transactions not supported; head is not a local branch");
final WorkingTree workingTree = delegate.getWorkingTree();
final String path = delegate.getTypeTreePath();
ProgressListener listener = new DefaultProgressListener();
final List<FeatureId> insertedFids = Lists.newArrayList();
List<Node> deferringTarget = new AbstractList<Node>() {
@Override
public boolean add(Node node) {
String fid = node.getName();
String version = node.getObjectId().toString();
insertedFids.add(new FeatureIdVersionedImpl(fid, version));
return true;
}
@Override
public Node get(int index) {
throw new UnsupportedOperationException();
}
@Override
public int size() {
return 0;
}
};
Integer count = (Integer) null;
FeatureIterator<SimpleFeature> featureIterator = featureCollection.features();
try {
Iterator<SimpleFeature> features;
features = new FeatureIteratorIterator<SimpleFeature>(featureIterator);
/*
* Make sure to transform the incoming features to the native schema to avoid situations
* where geogig would change the metadataId of the RevFeature nodes due to small
* differences in the default and incoming schema such as namespace or missing
* properties
*/
final SimpleFeatureType nativeSchema = delegate.getNativeType();
features = Iterators.transform(features, new SchemaInforcer(nativeSchema));
workingTree.insert(path, features, listener, deferringTarget, count);
} catch (Exception e) {
throw new IOException(e);
} finally {
featureIterator.close();
}
return insertedFids;
}
use of org.locationtech.geogig.api.Node in project GeoGig by boundlessgeo.
the class GeogigFeatureStore method modifyFeatures.
@Override
public void modifyFeatures(Name[] names, Object[] values, Filter filter) throws IOException {
Preconditions.checkState(getDataStore().isAllowTransactions(), "Transactions not supported; head is not a local branch");
final WorkingTree workingTree = delegate.getWorkingTree();
final String path = delegate.getTypeTreePath();
Iterator<SimpleFeature> features = modifyingFeatureIterator(names, values, filter);
/*
* Make sure to transform the incoming features to the native schema to avoid situations
* where geogig would change the metadataId of the RevFeature nodes due to small differences
* in the default and incoming schema such as namespace or missing properties
*/
final SimpleFeatureType nativeSchema = delegate.getNativeType();
features = Iterators.transform(features, new SchemaInforcer(nativeSchema));
try {
ProgressListener listener = new DefaultProgressListener();
Integer count = (Integer) null;
List<Node> target = (List<Node>) null;
workingTree.insert(path, features, listener, target, count);
} catch (Exception e) {
throw new IOException(e);
}
}
use of org.locationtech.geogig.api.Node in project GeoGig by boundlessgeo.
the class DepthSearch method find.
/**
* Searches for the direct child path in the parent tree.
*
* @param parent the tree to search
* @param parentPath the path of the parent tree
* @param childPath the path to search for
* @return an {@link Optional} of the {@code Node} if the child path was found, or
* {@link Optional#absent()} if it wasn't found.
*/
public Optional<NodeRef> find(final RevTree parent, final String parentPath, final String childPath) {
checkNotNull(parent, "parent");
checkNotNull(parentPath, "parentPath");
checkNotNull(childPath, "childPath");
checkArgument(parentPath.isEmpty() || parentPath.charAt(parentPath.length() - 1) != PATH_SEPARATOR);
checkArgument(!childPath.isEmpty(), "empty child path");
checkArgument(childPath.charAt(childPath.length() - 1) != PATH_SEPARATOR);
checkArgument(parentPath.isEmpty() || childPath.startsWith(parentPath + PATH_SEPARATOR));
final List<String> parentSteps = Lists.newArrayList(Splitter.on(PATH_SEPARATOR).omitEmptyStrings().split(parentPath));
List<String> childSteps = Lists.newArrayList(Splitter.on(PATH_SEPARATOR).split(childPath));
childSteps = childSteps.subList(parentSteps.size(), childSteps.size());
RevTree subTree = parent;
ObjectId metadataId = ObjectId.NULL;
for (int i = 0; i < childSteps.size() - 1; i++) {
String directChildName = childSteps.get(i);
Optional<Node> subtreeRef = getDirectChild(subTree, directChildName, 0);
if (!subtreeRef.isPresent()) {
return Optional.absent();
}
metadataId = subtreeRef.get().getMetadataId().or(ObjectId.NULL);
subTree = objectDb.get(subtreeRef.get().getObjectId(), RevTree.class);
}
final String childName = childSteps.get(childSteps.size() - 1);
Optional<Node> node = getDirectChild(subTree, childName, 0);
NodeRef result = null;
if (node.isPresent()) {
String nodeParentPath = NodeRef.parentPath(childPath);
result = new NodeRef(node.get(), nodeParentPath, node.get().getMetadataId().or(metadataId));
}
return Optional.fromNullable(result);
}
Aggregations