All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jsimpledb.kv.util.CloseableForwardingKVStore Maven / Gradle / Ivy

The newest version!

/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package org.jsimpledb.kv.util;

import com.google.common.base.Preconditions;

import java.io.Closeable;
import java.io.IOException;

import org.jsimpledb.kv.CloseableKVStore;
import org.jsimpledb.kv.KVStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A {@link ForwardingKVStore} also implementing {@link CloseableKVStore}, with some associated
 * underlying {@link Closeable} resource to close when {@link #close}'d.
 */
public class CloseableForwardingKVStore extends ForwardingKVStore implements CloseableKVStore {

    private static final boolean TRACK_ALLOCATIONS = Boolean.parseBoolean(
      System.getProperty(CloseableForwardingKVStore.class.getName() + ".TRACK_ALLOCATIONS", "false"));

    private final KVStore kvstore;
    private final Closeable closeable;
    private final Throwable allocation;

    private boolean closed;

    /**
     * Constructor for a do-nothing {@link #close}.
     *
     * 

* With this constructor, nothing will actually be closed when {@link #close} is invoked. * * @param kvstore key/value store for forwarding * @throws IllegalArgumentException if {@code kvstore} is null */ public CloseableForwardingKVStore(KVStore kvstore) { this(kvstore, null); } /** * Convenience constructor. * * @param kvstore key/value store for forwarding; will be closed on {@link #close} * @throws IllegalArgumentException if {@code kvstore} is null */ public CloseableForwardingKVStore(CloseableKVStore kvstore) { this(kvstore, kvstore); } /** * Primary constructor. * * @param kvstore key/value store for forwarding * @param resource {@link Closeable} resource, or null for none * @throws IllegalArgumentException if {@code kvstore} is null */ public CloseableForwardingKVStore(KVStore kvstore, Closeable resource) { Preconditions.checkArgument(kvstore != null, "null kvstore"); this.kvstore = kvstore; this.closeable = resource; this.allocation = CloseableForwardingKVStore.TRACK_ALLOCATIONS ? new Throwable("allocated here") : null; } @Override protected KVStore delegate() { return this.kvstore; } @Override public synchronized void close() { if (this.closed) return; try { if (this.closeable != null) this.closeable.close(); } catch (IOException e) { // ignore } this.closed = true; } /** * Ensure the associated resource is {@link #close}'d before reclaiming memory. */ @Override protected void finalize() throws Throwable { try { final boolean leaked; synchronized (this) { leaked = !this.closed; } if (leaked) { final Logger log = LoggerFactory.getLogger(this.getClass()); final String msg = this.getClass().getSimpleName() + "[" + this.closeable + "] leaked without invoking close()"; if (this.allocation != null) log.warn(msg, this.allocation); else log.warn(msg); this.close(); } } finally { super.finalize(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy