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

org.jsimpledb.kv.mvcc.SnapshotRefs Maven / Gradle / Ivy


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

package org.jsimpledb.kv.mvcc;

import com.google.common.base.Preconditions;

import java.io.Closeable;
import java.util.concurrent.atomic.AtomicInteger;

import net.jcip.annotations.ThreadSafe;

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

/**
 * Holds a count of references to a {@link CloseableKVStore} and actually {@link CloseableKVStore#close close()}'s it
 * when the reference count reaches zero.
 *
 * 

* Instances are thread safe. */ @ThreadSafe public class SnapshotRefs { private final CloseableKVStore snapshot; private final AtomicInteger refs = new AtomicInteger(1); /** * Constructor. * *

* Initially the reference count is set to one. * * @param snapshot database snapshot */ public SnapshotRefs(CloseableKVStore snapshot) { Preconditions.checkArgument(snapshot != null, "null snapshot"); this.snapshot = snapshot; } /** * Get the underlying database snapshot as a {@link KVStore} (which should not be closed). * * @throws IllegalStateException if reference count is already zeroed */ public KVStore getKVStore() { Preconditions.checkState(this.refs.get() > 0, "no longer referenced"); return this.snapshot; } /** * Increment reference count. * * @throws IllegalStateException if reference count is already zeroed */ public void ref() { Preconditions.checkState(this.refs.get() > 0, "no longer referenced"); this.refs.incrementAndGet(); } /** * Decrement reference count. * * @throws IllegalStateException if reference count is already zeroed */ public void unref() { Preconditions.checkState(this.refs.get() > 0, "no longer referenced"); if (this.refs.decrementAndGet() == 0) this.snapshot.close(); } /** * Get current reference count. */ public int refs() { return this.refs.get(); } /** * Create an empty {@link Closeable} that, when {@link Closeable#close close()}'d, decrements the reference count. * * @return unreferencing {@link Closeable} */ public Closeable getUnrefCloseable() { return new Closeable() { private boolean closed; @Override public synchronized void close() { if (this.closed) return; SnapshotRefs.this.unref(); this.closed = true; } }; } @Override protected void finalize() throws Throwable { try { final int remaining = this.refs.get(); if (remaining > 0) { LoggerFactory.getLogger(this.getClass()).warn(this + " leaked with " + remaining + " remaining reference(s)"); this.refs.set(0); this.snapshot.close(); } } finally { super.finalize(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy