Author: xedin Date: Mon Oct 31 15:43:23 2011 New Revision: 1195526 URL: http://svn.apache.org/viewvc?rev=1195526&view=rev Log: Cache for CompressionMetadata objects patch by Sylvain Lebresne; reviewed by Pavel Yaskevich for CASSANDRA-3427
Modified: cassandra/branches/cassandra-1.0/CHANGES.txt cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressionMetadata.java cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/CompressedSegmentedFile.java Modified: cassandra/branches/cassandra-1.0/CHANGES.txt URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/CHANGES.txt?rev=1195526&r1=1195525&r2=1195526&view=diff ============================================================================== --- cassandra/branches/cassandra-1.0/CHANGES.txt (original) +++ cassandra/branches/cassandra-1.0/CHANGES.txt Mon Oct 31 15:43:23 2011 @@ -2,6 +2,7 @@ * "defragment" rows for name-based queries under STCS (CASSANDRA-2503) * cleanup usage of StorageService.setMode() (CASANDRA-3388) * Add timing information to cassandra-cli GET/SET/LIST queries (CASSANDRA-3326) + * Cache for CompressionMetadata objects (CASSANDRA-3427) 1.0.1 * acquire references during index build to prevent delete problems Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java?rev=1195526&r1=1195525&r2=1195526&view=diff ============================================================================== --- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java (original) +++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java Mon Oct 31 15:43:23 2011 @@ -23,8 +23,6 @@ import java.nio.channels.FileChannel; import java.util.zip.CRC32; import java.util.zip.Checksum; -import org.apache.cassandra.io.sstable.Component; -import org.apache.cassandra.io.sstable.Descriptor; import org.apache.cassandra.io.util.RandomAccessReader; import org.apache.cassandra.utils.FBUtilities; @@ -36,31 +34,9 @@ public class CompressedRandomAccessReade { private static final Logger logger = LoggerFactory.getLogger(CompressedRandomAccessReader.class); - /** - * Get metadata about given compressed file including uncompressed data length, chunk size - * and list of the chunk offsets of the compressed data. - * - * @param dataFilePath Path to the compressed file - * - * @return metadata about given compressed file. - */ - public static CompressionMetadata metadata(String dataFilePath) - { - Descriptor desc = Descriptor.fromFilename(dataFilePath); - - try - { - return new CompressionMetadata(desc.filenameFor(Component.COMPRESSION_INFO), new File(dataFilePath).length()); - } - catch (IOException e) - { - throw new IOError(e); - } - } - public static RandomAccessReader open(String dataFilePath, boolean skipIOCache) throws IOException { - return open(dataFilePath, metadata(dataFilePath), skipIOCache); + return open(dataFilePath, CompressionMetadata.get(dataFilePath), skipIOCache); } public static RandomAccessReader open(String dataFilePath, CompressionMetadata metadata) throws IOException Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressionMetadata.java URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressionMetadata.java?rev=1195526&r1=1195525&r2=1195526&view=diff ============================================================================== --- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressionMetadata.java (original) +++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/compress/CompressionMetadata.java Mon Oct 31 15:43:23 2011 @@ -21,8 +21,11 @@ package org.apache.cassandra.io.compress import java.io.*; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.io.sstable.Component; +import org.apache.cassandra.io.sstable.Descriptor; import org.apache.cassandra.io.util.FileUtils; /** @@ -36,7 +39,53 @@ public class CompressionMetadata public final String indexFilePath; public final CompressionParameters parameters; - public CompressionMetadata(String indexFilePath, long compressedLength) throws IOException + /** + * Caches instances of CompressionMetadata. + * Each metada holds the chunk offsets index, which is reasonably big for + * enough data, so it's an expensive structure. We thus only want one + * CompressionMetadata created for each sstable. + * Note that we could have a compressionMetadata field in SSTableReader, + * but CompressedSegmentFile.Builder needs it before the reader is + * created, so it's easier that way. + */ + private final static Map<String, CompressionMetadata> cache = new ConcurrentHashMap<String, CompressionMetadata>(); + + /** + * Get metadata about given compressed file including uncompressed data length, chunk size + * and list of the chunk offsets of the compressed data. + * + * @param dataFilePath Path to the compressed file + * + * @return metadata about given compressed file. + */ + public static CompressionMetadata get(String dataFilePath) + { + CompressionMetadata metadata = cache.get(dataFilePath); + if (metadata != null) + return metadata; + + // We want this to be relatively fast, because it's called often (for each + // range query). On the side, we don't care too much if the initial + // creation is no thread-safe, because we'll call this when the + // SSTableReader is loaded/created, so we're pretty sure there won't + // be any contention. Besides, if we really do create two + // CompressionMetadata, it's not the end of the world, so we don't + // bother with synchronization + Descriptor desc = Descriptor.fromFilename(dataFilePath); + try + { + metadata = new CompressionMetadata(desc.filenameFor(Component.COMPRESSION_INFO), new File(dataFilePath).length()); + cache.put(dataFilePath, metadata); + return metadata; + } + catch (IOException e) + { + throw new IOError(e); + } + } + + // This is package protected because of the tests. Don't use, use get() instead. + CompressionMetadata(String indexFilePath, long compressedLength) throws IOException { this.indexFilePath = indexFilePath; Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/CompressedSegmentedFile.java URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/CompressedSegmentedFile.java?rev=1195526&r1=1195525&r2=1195526&view=diff ============================================================================== --- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/CompressedSegmentedFile.java (original) +++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/CompressedSegmentedFile.java Mon Oct 31 15:43:23 2011 @@ -52,7 +52,7 @@ public class CompressedSegmentedFile ext */ public SegmentedFile complete(String path) { - return new CompressedSegmentedFile(path, CompressedRandomAccessReader.metadata(path)); + return new CompressedSegmentedFile(path, CompressionMetadata.get(path)); } }