/* Copyright (c) 2013 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: * David Winslow (Boundless) - initial implementation */ package org.locationtech.geogig.storage.bdbje; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import org.locationtech.geogig.storage.DeduplicationService; import org.locationtech.geogig.storage.Deduplicator; import com.google.inject.Inject; import com.sleepycat.je.Database; import com.sleepycat.je.DatabaseConfig; import com.sleepycat.je.Environment; /** * A {@link DeduplicationService} that creates {@link DatabaseConfig#setTemporary(boolean) * temporary} BDB JE databases in the {@code .geogig/seen} environment upon every * {@link #createDatabase()} call. * <p> * The created temporary databases share the heap cache with the other JE databases, namely the * {@link JEObjectDatabase object} and {@link JEStagingDatabase staging} databases, and will page to * disk as appropriate when the BDB JE cache is full. * </p> * * @see BDBJEDeduplicator */ public class BDBJEDeduplicationService implements DeduplicationService { private EnvironmentBuilder environmentBuilder; private Set<BDBJEDeduplicator> openDeduplicators = new HashSet<BDBJEDeduplicator>(); private volatile Environment environment; private volatile AtomicInteger tick = new AtomicInteger(); @Inject public BDBJEDeduplicationService(EnvironmentBuilder environmentBuilder) { this.environmentBuilder = environmentBuilder; } private synchronized Environment getEnvironment() { if (this.environment == null) { this.environment = environmentBuilder.setRelativePath("seen").get(); } return this.environment; } private Database createDatabase() { DatabaseConfig dbConfig = new DatabaseConfig(); dbConfig.setAllowCreate(true); dbConfig.setDeferredWrite(false); dbConfig.setTransactional(false); dbConfig.setTemporary(true); return getEnvironment().openDatabase(null, "seen" + tick.incrementAndGet(), dbConfig); } @Override public Deduplicator createDeduplicator() { Database database = createDatabase(); BDBJEDeduplicator deduplicator = new BDBJEDeduplicator(database, this); this.openDeduplicators.add(deduplicator); return deduplicator; } protected void reset(BDBJEDeduplicator deduplicator) { deduplicator.setDatabase(createDatabase()); } public synchronized void deregister(BDBJEDeduplicator deduplicator) { this.openDeduplicators.remove(deduplicator); if (this.openDeduplicators.size() == 0) { this.environment.close(); this.environment = null; } } }