Package org.locationtech.geogig.api.plumbing.diff

Source Code of org.locationtech.geogig.api.plumbing.diff.DiffCountConsumerTest

/* 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.junit.Assert;
import org.junit.Before;
import org.junit.Test;
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.RevObject.TYPE;
import org.locationtech.geogig.api.RevTree;
import org.locationtech.geogig.api.RevTreeBuilder;
import org.locationtech.geogig.storage.ObjectDatabase;
import org.locationtech.geogig.storage.memory.HeapObjectDatabse;

/**
*
*/
public class DiffCountConsumerTest extends Assert {

    /**
     * All original feature noderefs have this objectid
     */
    private static final ObjectId FAKE_FEATURE_ID = ObjectId
            .forString("1100000000000000000000000000000000000000");

    /**
     * All changed feature noderefs have this objectid
     */
    private static final ObjectId FAKE_FEATURE_ID_CHANGED = ObjectId
            .forString("2200000000000000000000000000000000000000");

    private ObjectDatabase odb;

    private RevTree childrenFeatureTree;

    /** single level tree with 2 * {@link RevTree#NORMALIZED_SIZE_LIMIT} feature references */
    private RevTree bucketsFeatureTree;

    private RevTree childrenFeatureTypesTree;

    RevTreeBuilder childTree1;

    RevTreeBuilder childTree2;

    @Before
    public void setUp() {
        odb = new HeapObjectDatabse();
        odb.open();
        {
            RevTreeBuilder builder = createFeaturesTree("", 10);
            this.childrenFeatureTree = builder.build();
        }
        {
            RevTreeBuilder rootBuilder = new RevTreeBuilder(odb);
            childTree1 = createFeaturesTree("tree1", 10);
            createFeatureTypesTree(rootBuilder, "tree1", childTree1);
            childTree2 = createFeaturesTree("tree2", 5);
            createFeatureTypesTree(rootBuilder, "tree2", childTree2);
            childrenFeatureTypesTree = rootBuilder.build();
        }

        {
            RevTreeBuilder builder = createFeaturesTree("", 2 * RevTree.NORMALIZED_SIZE_LIMIT);
            this.bucketsFeatureTree = builder.build();
            assertTrue(bucketsFeatureTree.buckets().isPresent());
        }
    }

    private void createFeatureTypesTree(RevTreeBuilder rootBuilder, String treePath,
            RevTreeBuilder childBuilder) {
        RevTree childTree = childBuilder.build();
        odb.put(childTree);
        Node childRef = Node.create(treePath, childTree.getId(), ObjectId.NULL, TYPE.TREE, null);
        rootBuilder.put(childRef);
    }

    private DiffObjectCount count(RevTree left, RevTree right) {
        PreOrderDiffWalk visitor = new PreOrderDiffWalk(left, right, odb, odb);
        DiffCountConsumer consumer = new DiffCountConsumer(odb);
        visitor.walk(consumer);
        DiffObjectCount count = consumer.get();
        return count;
    }

    @Test
    public void testSameTree() {
        DiffObjectCount count = count(childrenFeatureTree, childrenFeatureTree);
        assertEquals(0, count.featureCount());
        assertEquals(0, count.treeCount());
    }

    @Test
    public void testChildrenEmpty() {
        assertEquals(childrenFeatureTree.size(), count(childrenFeatureTree, RevTree.EMPTY)
                .featureCount());
        assertEquals(childrenFeatureTree.size(), count(RevTree.EMPTY, childrenFeatureTree)
                .featureCount());
    }

    @Test
    public void testChildrenChildren() {
        RevTreeBuilder builder = new RevTreeBuilder(odb, childrenFeatureTree);
        RevTree changed = builder.remove("3").build();
        assertEquals(1, count(childrenFeatureTree, changed).featureCount());
        assertEquals(1, count(changed, childrenFeatureTree).featureCount());

        changed = builder.put(
                Node.create("new", FAKE_FEATURE_ID, ObjectId.NULL, TYPE.FEATURE, null)).build();
        assertEquals(2, count(childrenFeatureTree, changed).featureCount());
        assertEquals(2, count(changed, childrenFeatureTree).featureCount());

        changed = builder.put(
                Node.create("1", FAKE_FEATURE_ID_CHANGED, ObjectId.NULL, TYPE.FEATURE, null))
                .build();
        assertEquals(3, count(childrenFeatureTree, changed).featureCount());
        assertEquals(3, count(changed, childrenFeatureTree).featureCount());
    }

    @Test
    public void testChildrenChildrenNestedTrees() {
        RevTreeBuilder rootBuilder = new RevTreeBuilder(odb, childrenFeatureTypesTree);
        childTree1.put(featureRef("tree1", 1000));
        createFeatureTypesTree(rootBuilder, "tree1", childTree1);
        RevTree newRoot = rootBuilder.build();

        assertEquals(1, count(childrenFeatureTypesTree, newRoot).featureCount());

        childTree2.remove("tree2/2");
        createFeatureTypesTree(rootBuilder, "tree2", childTree2);
        newRoot = rootBuilder.build();
        assertEquals(2, count(childrenFeatureTypesTree, newRoot).featureCount());

        childTree2.put(Node.create("tree2/1", FAKE_FEATURE_ID_CHANGED, ObjectId.NULL, TYPE.FEATURE,
                null));
        createFeatureTypesTree(rootBuilder, "tree2", childTree2);
        newRoot = rootBuilder.build();
        assertEquals(3, count(childrenFeatureTypesTree, newRoot).featureCount());
    }

    @Test
    public void testBucketBucketAdd() {
        RevTreeBuilder builder = new RevTreeBuilder(odb, bucketsFeatureTree);

        final int initialSize = (int) bucketsFeatureTree.size();
        final int added = 1 + 2 * RevTree.NORMALIZED_SIZE_LIMIT;
        for (int i = initialSize; i < (initialSize + added); i++) {
            builder.put(featureRef("", i));
        }

        RevTree changed = builder.build();
        assertEquals(initialSize + added, changed.size());

        assertEquals(added, count(bucketsFeatureTree, changed).featureCount());
        assertEquals(added, count(changed, bucketsFeatureTree).featureCount());

        assertEquals(added, count(bucketsFeatureTree, changed).getFeaturesAdded());
        assertEquals(0, count(bucketsFeatureTree, changed).getFeaturesChanged());
        assertEquals(0, count(bucketsFeatureTree, changed).getFeaturesRemoved());

        // invert the comparison
        assertEquals(0, count(changed, bucketsFeatureTree).getFeaturesAdded());
        assertEquals(added, count(changed, bucketsFeatureTree).getFeaturesRemoved());
        assertEquals(0, count(changed, bucketsFeatureTree).getFeaturesChanged());
    }

    @Test
    public void testBucketBucketRemove() {
        RevTreeBuilder builder = new RevTreeBuilder(odb, bucketsFeatureTree);

        RevTree changed;
        changed = builder.remove("3").build();
        assertEquals(1, count(bucketsFeatureTree, changed).featureCount());
        assertEquals(1, count(changed, bucketsFeatureTree).featureCount());

        for (int i = 0; i < RevTree.NORMALIZED_SIZE_LIMIT - 1; i++) {
            builder.remove(String.valueOf(i));
        }
        changed = builder.build();
        assertEquals(RevTree.NORMALIZED_SIZE_LIMIT + 1, changed.size());
        assertTrue(changed.buckets().isPresent());

        assertEquals(RevTree.NORMALIZED_SIZE_LIMIT - 1, count(bucketsFeatureTree, changed)
                .featureCount());
        assertEquals(RevTree.NORMALIZED_SIZE_LIMIT - 1, count(changed, bucketsFeatureTree)
                .featureCount());

        builder.remove(String.valueOf(RevTree.NORMALIZED_SIZE_LIMIT + 1));

        changed = builder.build();
        assertEquals(RevTree.NORMALIZED_SIZE_LIMIT, changed.size());
        assertFalse(changed.buckets().isPresent());
    }

    @Test
    public void testBucketBucketChange() {
        RevTreeBuilder builder;
        RevTree changed;

        builder = new RevTreeBuilder(odb, bucketsFeatureTree);

        changed = builder.put(
                Node.create("1023", FAKE_FEATURE_ID_CHANGED, ObjectId.NULL, TYPE.FEATURE, null))
                .build();
        DiffObjectCount count = count(bucketsFeatureTree, changed);
        assertEquals(1, count.featureCount());
        assertEquals(0, count.treeCount());
        count = count(changed, bucketsFeatureTree);
        assertEquals(1, count.featureCount());
        assertEquals(0, count.treeCount());

        builder = new RevTreeBuilder(odb, bucketsFeatureTree);
        int expected = 0;
        for (int i = 0; i < bucketsFeatureTree.size(); i += 2) {
            changed = builder.put(
                    Node.create(String.valueOf(i), FAKE_FEATURE_ID_CHANGED, ObjectId.NULL,
                            TYPE.FEATURE, null)).build();
            expected++;
        }
        changed = builder.build();
        assertEquals(expected, count(bucketsFeatureTree, changed).featureCount());
        assertEquals(expected, count(changed, bucketsFeatureTree).featureCount());

        assertEquals(expected, count(bucketsFeatureTree, changed).getFeaturesChanged());
        assertEquals(expected, count(changed, bucketsFeatureTree).getFeaturesChanged());
        assertEquals(0, count(changed, bucketsFeatureTree).getFeaturesAdded());
        assertEquals(0, count(changed, bucketsFeatureTree).getFeaturesRemoved());
    }

    @Test
    public void testBucketChildren() {
        RevTreeBuilder builder = new RevTreeBuilder(odb, bucketsFeatureTree);
        RevTree changed;
        for (int i = 0; i < RevTree.NORMALIZED_SIZE_LIMIT; i++) {
            builder.remove(String.valueOf(i));
        }
        changed = builder.build();
        assertEquals(RevTree.NORMALIZED_SIZE_LIMIT, changed.size());
        assertFalse(changed.buckets().isPresent());

        assertEquals(RevTree.NORMALIZED_SIZE_LIMIT, count(bucketsFeatureTree, changed)
                .featureCount());
        assertEquals(RevTree.NORMALIZED_SIZE_LIMIT, count(changed, bucketsFeatureTree)
                .featureCount());
    }

    @Test
    public void testBucketChildrenDeeperBuckets() {

        final RevTree deepTree = createFeaturesTree("", 20000 + RevTree.NORMALIZED_SIZE_LIMIT)
                .build();
        // sanity check
        assertTrue(deepTree.buckets().isPresent());

        {// sanity check to ensure we're testing with a tree with depth > 1 (i.e. at least two
         // levels of buckets)
            final int maxDepth = depth(deepTree, 0);
            assertTrue(maxDepth > 1);
        }

        RevTreeBuilder builder = new RevTreeBuilder(odb, deepTree);
        {
            final int count = (int) (deepTree.size() - RevTree.NORMALIZED_SIZE_LIMIT);
            for (int i = 0; i < count; i++) {
                String path = String.valueOf(i);
                builder.remove(path);
            }
        }
        RevTree changed = builder.build();
        assertEquals(RevTree.NORMALIZED_SIZE_LIMIT, changed.size());
        // sanity check
        assertTrue(changed.features().isPresent());
        assertFalse(changed.buckets().isPresent());

        final long expected = deepTree.size() - changed.size();

        assertEquals(expected, count(deepTree, changed).featureCount());
        assertEquals(expected, count(changed, deepTree).featureCount());
    }

    private int depth(RevTree deepTree, int currDepth) {
        if (!deepTree.buckets().isPresent()) {
            return currDepth;
        }
        int depth = currDepth;
        for (Bucket bucket : deepTree.buckets().get().values()) {
            RevTree bucketTree = odb.get(bucket.id(), RevTree.class);
            int d = depth(bucketTree, currDepth + 1);
            depth = Math.max(depth, d);
        }
        return depth;
    }

    private RevTreeBuilder createFeaturesTree(final String parentPath, final int numEntries) {

        RevTreeBuilder tree = new RevTreeBuilder(odb);
        for (int i = 0; i < numEntries; i++) {
            tree.put(featureRef(parentPath, i));
        }
        return tree;
    }

    private Node featureRef(String parentPath, int i) {
        String path = NodeRef.appendChild(parentPath, String.valueOf(i));
        Node ref = Node.create(path, FAKE_FEATURE_ID, ObjectId.NULL, TYPE.FEATURE, null);
        return ref;
    }

}
TOP

Related Classes of org.locationtech.geogig.api.plumbing.diff.DiffCountConsumerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.