Package org.locationtech.geogig.repository

Source Code of org.locationtech.geogig.repository.RevTreeBuilder2

/* Copyright (c) 2013-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.repository;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;

import javax.annotation.Nullable;

import org.locationtech.geogig.api.Node;
import org.locationtech.geogig.api.ObjectId;
import org.locationtech.geogig.api.Platform;
import org.locationtech.geogig.api.RevFeatureType;
import org.locationtech.geogig.api.RevFeatureTypeImpl;
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.opengis.feature.type.FeatureType;
import org.opengis.feature.type.Name;
import org.opengis.geometry.BoundingBox;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.vividsolutions.jts.geom.Envelope;

class RevTreeBuilder2 {

    private static final Logger LOGGER = LoggerFactory.getLogger(RevTreeBuilder2.class);

    private final NodeIndex nodeIndex;

    private final ObjectDatabase db;

    private final RevTree original;

    private final Map<Name, RevFeatureType> revFeatureTypes = Maps.newConcurrentMap();

    private final ObjectId defaultMetadataId;

    /**
     * Copy constructor
     */
    public RevTreeBuilder2(final ObjectDatabase db, @Nullable final RevTree origTree,
            final ObjectId defaultMetadataId, final Platform platform,
            final ExecutorService executorService) {

        this.db = db;
        this.original = origTree;
        this.defaultMetadataId = defaultMetadataId;
        this.nodeIndex = new FileNodeIndex(platform, executorService);
    }

    public ObjectId getDefaultMetadataId() {
        return defaultMetadataId;
    }

    /**
     * Adds or replaces an element in the tree with the given key.
     * <p>
     * <!-- Implementation detail: If the number of cached entries (entries held directly by this
     * tree) reaches {@link #DEFAULT_NORMALIZATION_THRESHOLD}, this tree will {@link #normalize()}
     * itself.
     *
     * -->
     *
     * @param key non null
     * @param value non null
     */
    public synchronized RevTreeBuilder2 put(final Node node) {
        Preconditions.checkNotNull(node, "node can't be null");
        nodeIndex.add(node);
        return this;
    }

    /**
     * Traverses the nodes in the {@link NodeIndex}, deletes the ones with {@link ObjectId#NULL
     * NULL} ObjectIds, and adds the ones with non "NULL" ids.
     *
     * @return the new tree, not saved to the object database. Any bucket tree though is saved when
     *         this method returns.
     */
    public RevTree build() {
        if (nodeIndex == null) {
            return original.builder(db).build();
        }

        Stopwatch sw = Stopwatch.createStarted();
        RevTreeBuilder builder;
        try {
            builder = new RevTreeBuilder(db, original);
            Iterator<Node> nodes = nodeIndex.nodes();
            while (nodes.hasNext()) {
                Node node = nodes.next();
                if (node.getObjectId().isNull()) {
                    builder.remove(node.getName());
                } else {
                    builder.put(node);
                }
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
            throw e;
        } finally {
            nodeIndex.close();
        }
        LOGGER.debug("Index traversed in {}", sw.stop());
        sw.reset().start();

        RevTree namedTree = builder.build();
        saveExtraFeatureTypes();
        LOGGER.debug("RevTreeBuilder.build() in {}", sw.stop());
        return namedTree;
    }

    private void saveExtraFeatureTypes() {
        Collection<RevFeatureType> types = revFeatureTypes.values();
        List<RevFeatureType> nonDefaults = Lists.newLinkedList();
        for (RevFeatureType t : types) {
            if (!t.getId().equals(defaultMetadataId)) {
                nonDefaults.add(t);
            }
        }
        if (!nonDefaults.isEmpty()) {
            db.putAll(nonDefaults.iterator());
        }
    }

    public Node putFeature(final ObjectId id, final String name,
            @Nullable final BoundingBox bounds, final FeatureType type) {
        Envelope bbox;
        if (bounds == null) {
            bbox = null;
        } else if (bounds instanceof Envelope) {
            bbox = (Envelope) bounds;
        } else {
            bbox = new Envelope(bounds.getMinimum(0), bounds.getMaximum(0), bounds.getMinimum(1),
                    bounds.getMaximum(1));
        }
        RevFeatureType revFeatureType = revFeatureTypes.get(type.getName());
        if (null == revFeatureType) {
            revFeatureType = RevFeatureTypeImpl.build(type);
            revFeatureTypes.put(type.getName(), revFeatureType);
        }
        ObjectId metadataId = revFeatureType.getId().equals(defaultMetadataId) ? ObjectId.NULL
                : revFeatureType.getId();
        Node node = Node.create(name, id, metadataId, TYPE.FEATURE, bbox);
        put(node);
        return node;
    }

    /**
     * Marks the node named after {@code fid} to be deleted by adding a Node with
     * {@link ObjectId#NULL NULL} ObjectId
     */
    public void removeFeature(String fid) {
        Node node = Node.create(fid, ObjectId.NULL, ObjectId.NULL, TYPE.FEATURE, null);
        put(node);
    }

}
TOP

Related Classes of org.locationtech.geogig.repository.RevTreeBuilder2

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.