/* 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.storage;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import org.locationtech.geogig.api.ObjectId;
import org.locationtech.geogig.api.RevCommit;
import org.locationtech.geogig.api.RevFeature;
import org.locationtech.geogig.api.RevFeatureType;
import org.locationtech.geogig.api.RevObject;
import org.locationtech.geogig.api.RevTag;
import org.locationtech.geogig.api.RevTree;
import com.google.common.base.Supplier;
import com.google.inject.Inject;
/**
* A base class for {@link StagingDatabase}s that forward all {@link ObjectDatabase} change methods
* to the corresponding "staging" object database, and delegates all query methods to both databases
* as appropriate.
*/
public abstract class AbstractStagingDatabase implements StagingDatabase {
protected ObjectDatabase repositoryDb;
protected volatile ObjectDatabase stagingDb;
private Supplier<? extends ObjectDatabase> repositoryDbSupplier;
private Supplier<? extends ObjectDatabase> stagingDbSupplier;
/**
* @param repositoryDb the repository reference database, used to get delegate read operations
* to for objects not found here
*/
@Inject
public AbstractStagingDatabase(final Supplier<? extends ObjectDatabase> repositoryDb,
final Supplier<? extends ObjectDatabase> stagingDb) {
this.repositoryDbSupplier = repositoryDb;
this.stagingDbSupplier = stagingDb;
}
// /////////////////////////////////////////
private synchronized ObjectDatabase getStagingDb() {
if (stagingDb == null) {
stagingDb = stagingDbSupplier.get();
repositoryDb = repositoryDbSupplier.get();
}
return stagingDb;
}
@Override
public void open() {
getStagingDb().open();
}
@Override
public boolean isOpen() {
return getStagingDb().isOpen();
}
@Override
public void close() {
getStagingDb().close();
}
@Override
public RevTree getTree(ObjectId id) {
return get(id, RevTree.class);
}
@Override
public RevFeature getFeature(ObjectId id) {
return get(id, RevFeature.class);
}
@Override
public RevFeatureType getFeatureType(ObjectId id) {
return get(id, RevFeatureType.class);
}
@Override
public RevCommit getCommit(ObjectId id) {
return get(id, RevCommit.class);
}
@Override
public RevTag getTag(ObjectId id) {
return get(id, RevTag.class);
}
@Override
public boolean put(RevObject object) {
// if (repositoryDb.exists(object.getId())) {
// return false;
// }
return stagingDb.put(object);
}
@Override
public Iterator<RevObject> getAll(Iterable<ObjectId> ids) {
return getAll(ids, BulkOpListener.NOOP_LISTENER);
}
@Override
public Iterator<RevObject> getAll(final Iterable<ObjectId> ids, final BulkOpListener listener) {
return StagingDbCompositionHelper.getAll(repositoryDb, stagingDb, ids, listener);
}
@Override
public void putAll(Iterator<? extends RevObject> objects) {
stagingDb.putAll(objects);
}
@Override
public void putAll(Iterator<? extends RevObject> objects, BulkOpListener listener) {
stagingDb.putAll(objects, listener);
}
@Override
public long deleteAll(Iterator<ObjectId> ids) {
return deleteAll(ids, BulkOpListener.NOOP_LISTENER);
}
@Override
public long deleteAll(Iterator<ObjectId> ids, BulkOpListener listener) {
return stagingDb.deleteAll(ids, listener);
}
@Override
public boolean exists(ObjectId id) {
boolean exists = stagingDb.exists(id) || repositoryDb.exists(id);
return exists;
}
@Override
public List<ObjectId> lookUp(String partialId) {
Set<ObjectId> lookUp = new HashSet<ObjectId>(stagingDb.lookUp(partialId));
lookUp.addAll(repositoryDb.lookUp(partialId));
return new ArrayList<ObjectId>(lookUp);
}
@Override
public <T extends RevObject> T get(ObjectId id, Class<T> type) {
T obj = stagingDb.getIfPresent(id, type);
if (null == obj) {
obj = repositoryDb.get(id, type);
}
return obj;
}
@Override
@Nullable
public <T extends RevObject> T getIfPresent(ObjectId id, Class<T> clazz)
throws IllegalArgumentException {
T obj = stagingDb.getIfPresent(id, clazz);
if (null == obj) {
obj = repositoryDb.getIfPresent(id, clazz);
}
return obj;
}
@Override
public RevObject get(ObjectId id) {
RevObject obj = stagingDb.getIfPresent(id);
if (null == obj) {
obj = repositoryDb.get(id);
}
return obj;
}
@Override
public @Nullable
RevObject getIfPresent(ObjectId id) {
RevObject obj = stagingDb.getIfPresent(id);
if (null == obj) {
obj = repositoryDb.getIfPresent(id);
}
return obj;
}
@Override
public ObjectInserter newObjectInserter() {
return stagingDb.newObjectInserter();
}
@Override
public boolean delete(ObjectId objectId) {
return stagingDb.delete(objectId);
}
}