package com.indeed.mph; import com.indeed.util.core.reference.AtomicSharedReference; import com.indeed.util.core.reference.SharedReference; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.Closeable; import java.io.File; import java.io.IOException; /** * Thread-safe reference counting version of TableReader. * * @author alexs */ public class SharedTableReader<K, V> implements Closeable { private final AtomicSharedReference<TableReader<K, V>> reader; public SharedTableReader(@Nonnull final TableReader<K, V> reader) { this.reader = AtomicSharedReference.create(reader); } @Override public void close() throws IOException { reader.unset(); } public static <K, V> SharedTableReader<K, V> open(@Nonnull final File metaPath, @Nullable final File offsetsPath, @Nullable final File dataPath) throws IOException { return new SharedTableReader<>(TableReader.open(metaPath, offsetsPath, dataPath)); } public static <K, V> SharedTableReader<K, V> open(@Nonnull final File metaPath) throws IOException { return open(metaPath, null, null); } public static <K, V> SharedTableReader<K, V> open(@Nonnull final String metaPath) throws IOException { return open(new File(metaPath)); } public SharedReference<TableReader<K, V>> getCopy() { return reader.getCopy(); } public TableConfig<K, V> getConfig() throws IOException { try (final SharedReference<TableReader<K, V>> reader = getCopy()) { return reader.get().getMeta().getConfig(); } } public TableReader.TableStats getStats() throws IOException { try (final SharedReference<TableReader<K, V>> reader = getCopy()) { return reader.get().getStats(); } } public boolean containsKey(@Nonnull final K key) { try (final SharedReference<TableReader<K, V>> reader = getCopy()) { if (reader.get().getMeta().getConfig().getKeyValidator() == null) { return reader.get().getOffset(key) >= 0; } return get(key) != null; } catch (final IOException e) { return false; } } public V get(@Nonnull final K key) throws IOException { try (final SharedReference<TableReader<K, V>> reader = getCopy()) { final TableReader<K, V> r = reader == null ? null : reader.get(); if (r == null) { throw new IOException("table was already closed fetching: " + key); } return r.get(key); } } public long size() { try (final SharedReference<TableReader<K, V>> reader = getCopy()) { return reader.get().getMeta().numEntries(); } catch (final IOException e) { return 0L; } } public long getSizeInBytes() { try (final SharedReference<TableReader<K, V>> reader = getCopy()) { return reader.get().getSizeInBytes(); } catch (final IOException e) { return 0L; } } public long getTimestamp() { try (final SharedReference<TableReader<K, V>> reader = getCopy()) { return reader.get().getMeta().getTimestamp(); } catch (final IOException e) { return 0L; } } }