You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by xe...@apache.org on 2011/10/31 16:43:23 UTC

svn commit: r1195526 - in /cassandra/branches/cassandra-1.0: ./ src/java/org/apache/cassandra/io/compress/ src/java/org/apache/cassandra/io/util/

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));
         }
     }