cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jbel...@apache.org
Subject svn commit: r993171 - in /cassandra/trunk: src/java/org/apache/cassandra/db/ src/java/org/apache/cassandra/io/sstable/ src/java/org/apache/cassandra/io/util/ src/java/org/apache/cassandra/tools/ test/unit/org/apache/cassandra/io/sstable/
Date Mon, 06 Sep 2010 22:47:44 GMT
Author: jbellis
Date: Mon Sep  6 22:47:44 2010
New Revision: 993171

URL: http://svn.apache.org/viewvc?rev=993171&view=rev
Log:
Incorporate Components into ColumnFamilyStore loading: no more matching Data.db, etc!
patch by Stu Hood; reviewed by jbellis for CASSANDRA-1471

Added:
    cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Component.java
Modified:
    cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
    cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
    cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Descriptor.java
    cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java
    cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java
    cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
    cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
    cassandra/trunk/src/java/org/apache/cassandra/io/util/FileUtils.java
    cassandra/trunk/src/java/org/apache/cassandra/tools/SSTableExport.java
    cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java
    cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java

Modified: cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Mon Sep  6 22:47:44 2010
@@ -27,8 +27,6 @@ import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import com.google.common.collect.Iterables;
 import org.apache.commons.collections.IteratorUtils;
@@ -53,6 +51,7 @@ import org.apache.cassandra.db.marshal.A
 import org.apache.cassandra.db.marshal.BytesType;
 import org.apache.cassandra.db.marshal.LocalByPartionerType;
 import org.apache.cassandra.dht.*;
+import org.apache.cassandra.io.sstable.Component;
 import org.apache.cassandra.io.sstable.Descriptor;
 import org.apache.cassandra.io.sstable.SSTable;
 import org.apache.cassandra.io.sstable.SSTableReader;
@@ -64,6 +63,7 @@ import org.apache.cassandra.thrift.Index
 import org.apache.cassandra.thrift.IndexOperator;
 import org.apache.cassandra.utils.FBUtilities;
 import org.apache.cassandra.utils.LatencyTracker;
+import org.apache.cassandra.utils.Pair;
 import org.apache.cassandra.utils.WrappedRunnable;
 
 import javax.management.MBeanServer;
@@ -104,14 +104,6 @@ public class ColumnFamilyStore implement
                                                new NamedThreadFactory("FLUSH-WRITER-POOL"));
     private static ExecutorService postFlushExecutor = new JMXEnabledThreadPoolExecutor("MEMTABLE-POST-FLUSHER");
     
-    private static final FilenameFilter DB_NAME_FILTER = new FilenameFilter()
-    {
-        public boolean accept(File dir, String name)
-        {
-            return name.matches("[^\\.][\\S]+?[\\.db]");
-        }
-    };
-
     private Set<Memtable> memtablesPendingFlush = new ConcurrentSkipListSet<Memtable>();
 
     public final String table;
@@ -154,34 +146,18 @@ public class ColumnFamilyStore implement
         if (logger.isDebugEnabled())
             logger.debug("Starting CFS {}", columnFamily);
         
-        // scan for data files corresponding to this CF
-        List<File> sstableFiles = new ArrayList<File>();
-        
-        for (File file : files(table, columnFamilyName))
-        {
-            if (file.getName().contains("-Data.db"))
-            {
-                sstableFiles.add(file.getAbsoluteFile());
-            }
-        }
-        Collections.sort(sstableFiles, new FileUtils.FileComparator());
-
-        /* Load the index files and the Bloom Filters associated with them. */
+        // scan for sstables corresponding to this cf and load them
         List<SSTableReader> sstables = new ArrayList<SSTableReader>();
-        for (File file : sstableFiles)
+        for (Map.Entry<Descriptor,Set<Component>> sstableFiles : files(table, columnFamilyName).entrySet())
         {
-            String filename = file.getAbsolutePath();
-            if (SSTable.deleteIfCompacted(filename))
-                continue;
-
             SSTableReader sstable;
             try
             {
-                sstable = SSTableReader.open(Descriptor.fromFilename(filename), metadata, this.partitioner);
+                sstable = SSTableReader.open(sstableFiles.getKey(), sstableFiles.getValue(), metadata, this.partitioner);
             }
             catch (IOException ex)
             {
-                logger.error("Corrupt file " + filename + "; skipped", ex);
+                logger.error("Corrupt sstable " + sstableFiles + "; skipped", ex);
                 continue;
             }
             sstables.add(sstable);
@@ -311,68 +287,44 @@ public class ColumnFamilyStore implement
 
     public static synchronized ColumnFamilyStore createColumnFamilyStore(String table, String columnFamily, IPartitioner partitioner, CFMetaData metadata)
     {
-        /*
-         * Get all data files associated with old Memtables for this table.
-         * These files are named as follows <Table>-1.db, ..., <Table>-n.db. Get
-         * the max which in this case is n and increment it to use it for next
-         * index.
-         */
+        // get the max generation number, to prevent generation conflicts
         List<Integer> generations = new ArrayList<Integer>();
-        String[] dataFileDirectories = DatabaseDescriptor.getAllDataFileLocationsForTable(table);
-        for (String directory : dataFileDirectories)
-        {
-            File fileDir = new File(directory);
-            File[] files = fileDir.listFiles(DB_NAME_FILTER);
-            
-            for (File file : files)
-            {
-                if (file.isDirectory())
-                    continue;
-                String filename = file.getAbsolutePath();
-                String cfName = getColumnFamilyFromFileName(filename);
-
-                if (cfName.equals(columnFamily))
-                {
-                    generations.add(getGenerationFromFileName(filename));
-                }
-            }
-        }
+        for (Descriptor desc : files(table, columnFamily).keySet())
+            generations.add(desc.generation);
         Collections.sort(generations);
         int value = (generations.size() > 0) ? (generations.get(generations.size() - 1)) : 0;
 
         return new ColumnFamilyStore(table, columnFamily, partitioner, value, metadata);
     }
     
-    // remove unnecessary files from the cf directory. these include temp files, orphans and zero-length files.
+    /**
+     * Removes unnecessary files from the cf directory at startup: these include temp files, orphans, zero-length files
+     * and compacted sstables. Files that cannot be recognized will be ignored.
+     * @return A list of Descriptors that were removed.
+     */
     static void scrubDataDirectories(String table, String columnFamily)
     {
-        /* look for and remove orphans. An orphan is a -Filter.db or -Index.db with no corresponding -Data.db. */
-        Pattern auxFilePattern = Pattern.compile("(.*)(-Filter\\.db$|-Index\\.db$)");
-        for (File file : files(table, columnFamily))
-        {
-            String filename = file.getName();
-            Matcher matcher = auxFilePattern.matcher(file.getAbsolutePath());
-            if (matcher.matches())
-            {
-                String basePath = matcher.group(1);
-                if (!new File(basePath + "-Data.db").exists())
-                {
-                    logger.info(String.format("Removing orphan %s", file.getAbsolutePath()));
-                    try
-                    {
-                        FileUtils.deleteWithConfirm(file);
-                    }
-                    catch (IOException e)
-                    {
-                        throw new IOError(e);
-                    }
-                }
-            }
-            else if (((file.length() == 0 && !filename.endsWith("-Compacted")) || (filename.contains("-" + SSTable.TEMPFILE_MARKER))))
+        for (Map.Entry<Descriptor,Set<Component>> sstableFiles : files(table, columnFamily).entrySet())
+        {
+            Descriptor desc = sstableFiles.getKey();
+            Set<Component> components = sstableFiles.getValue();
+
+            if (SSTable.conditionalDelete(desc, components))
+                // was compacted or temporary: deleted.
+                continue;
+
+            File dataFile = new File(desc.filenameFor(Component.DATA));
+            if (components.contains(Component.DATA) && dataFile.length() > 0)
+                // everything appears to be in order... moving on.
+                continue;
+
+            // missing the DATA file! all components are orphaned
+            logger.warn("Removing orphans for {}: {}", desc, components);
+            for (Component component : components)
             {
                 try
                 {
-                    FileUtils.deleteWithConfirm(file);
+                    FileUtils.deleteWithConfirm(desc.filenameFor(component));
                 }
                 catch (IOException e)
                 {
@@ -382,26 +334,36 @@ public class ColumnFamilyStore implement
         }
     }
     
-    private static Set<File> files(String table, String columnFamily)
+    /**
+     * Collects a map of sstable components.
+     */
+    private static Map<Descriptor,Set<Component>> files(String keyspace, final String columnFamily)
     {
-        assert table != null;
-        assert columnFamily != null;
-        Set<File> fileSet = new HashSet<File>();
-        for (String directory : DatabaseDescriptor.getAllDataFileLocationsForTable(table))
+        final Map<Descriptor,Set<Component>> sstables = new HashMap<Descriptor,Set<Component>>();
+        for (String directory : DatabaseDescriptor.getAllDataFileLocationsForTable(keyspace))
         {
-            File[] files = new File(directory).listFiles(DB_NAME_FILTER);
-            if (files == null)
-                continue;
-            for (File file : files)
+            // NB: we never "accept" a file in the FilenameFilter sense: they are added to the sstable map
+            new File(directory).list(new FilenameFilter()
             {
-                if (file.isDirectory())
-                    continue;
-                String cfName = getColumnFamilyFromFileName(file.getAbsolutePath());
-                if (cfName.equals(columnFamily))
-                    fileSet.add(file);
-            }
+                @Override
+                public boolean accept(File dir, String name)
+                {
+                    Pair<Descriptor,Component> component = SSTable.tryComponentFromFilename(dir, name);
+                    if (component != null && component.left.cfname.equals(columnFamily))
+                    {
+                        Set<Component> components = sstables.get(component.left);
+                        if (components == null)
+                        {
+                            components = new HashSet<Component>();
+                            sstables.put(component.left, components);
+                        }
+                        components.add(component.right);
+                    }
+                    return false;
+                }
+            });
         }
-        return fileSet;
+        return sstables;
     }
 
     /**
@@ -412,16 +374,6 @@ public class ColumnFamilyStore implement
         return columnFamily;
     }
 
-    private static String getColumnFamilyFromFileName(String filename)
-    {
-        return Descriptor.fromFilename(filename).cfname;
-    }
-
-    public static int getGenerationFromFileName(String filename)
-    {
-        return Descriptor.fromFilename(filename).generation;
-    }
-
     /*
      * @return a temporary file name for an sstable.
      * When the sstable object is closed, it will be renamed to a non-temporary
@@ -439,11 +391,11 @@ public class ColumnFamilyStore implement
     public String getTempSSTablePath(String directory)
     {
         Descriptor desc = new Descriptor(new File(directory),
-                table,
-                columnFamily,
-                                                         fileIndexGenerator.incrementAndGet(),
-                                                         true);
-        return desc.filenameFor("Data.db");
+                                         table,
+                                         columnFamily,
+                                         fileIndexGenerator.incrementAndGet(),
+                                         true);
+        return desc.filenameFor(Component.DATA);
     }
 
     /** flush the given memtable and swap in a new one for its CFS, if it hasn't been frozen already.  threadsafe. */
@@ -1336,25 +1288,20 @@ public class ColumnFamilyStore implement
             try
             {
                 // mkdir
-                File sourceFile = new File(ssTable.getFilename());
-                File dataDirectory = sourceFile.getParentFile().getParentFile();
+                File dataDirectory = ssTable.getDescriptor().directory.getParentFile();
                 String snapshotDirectoryPath = Table.getSnapshotPath(dataDirectory.getAbsolutePath(), table, snapshotName);
                 FileUtils.createDirectory(snapshotDirectoryPath);
 
                 // hard links
-                File targetLink = new File(snapshotDirectoryPath, sourceFile.getName());
-                FileUtils.createHardLink(sourceFile, targetLink);
-
-                sourceFile = new File(ssTable.indexFilename());
-                targetLink = new File(snapshotDirectoryPath, sourceFile.getName());
-                FileUtils.createHardLink(sourceFile, targetLink);
-
-                sourceFile = new File(ssTable.filterFilename());
-                targetLink = new File(snapshotDirectoryPath, sourceFile.getName());
-                FileUtils.createHardLink(sourceFile, targetLink);
+                for (Component component : ssTable.getComponents())
+                {
+                    File sourceFile = new File(ssTable.getDescriptor().filenameFor(component));
+                    File targetLink = new File(snapshotDirectoryPath, sourceFile.getName());
+                    FileUtils.createHardLink(sourceFile, targetLink);
+                }
                 if (logger.isDebugEnabled())
-                    logger.debug("Snapshot for " + table + " table data file " + sourceFile.getAbsolutePath() +
-                        " created as " + targetLink.getAbsolutePath());
+                    logger.debug("Snapshot for " + table + " keyspace data file " + ssTable.getFilename() +
+                        " created in " + snapshotDirectoryPath);
             }
             catch (IOException e)
             {

Modified: cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/Table.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/Table.java Mon Sep  6 22:47:44 2010
@@ -32,6 +32,8 @@ import com.google.common.collect.Iterabl
 import org.apache.cassandra.config.*;
 import org.apache.cassandra.db.commitlog.CommitLog;
 import org.apache.cassandra.dht.LocalToken;
+import org.apache.cassandra.io.sstable.Component;
+import org.apache.cassandra.io.sstable.Descriptor;
 import org.apache.cassandra.io.sstable.SSTableDeletingReference;
 import org.apache.cassandra.io.sstable.SSTableReader;
 import org.apache.cassandra.io.util.FileUtils;
@@ -98,9 +100,8 @@ public class Table
                 {
                     // do some housekeeping on the column families.
                     for (CFMetaData cfm : DatabaseDescriptor.getTableDefinition(table).cfMetaData().values())
-                    {
                         ColumnFamilyStore.scrubDataDirectories(table, cfm.cfName);
-                    }
+                    // open and store the table
                     tableInstance = new Table(table);
                     instances.put(table, tableInstance);
                 }

Added: cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Component.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Component.java?rev=993171&view=auto
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Component.java (added)
+++ cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Component.java Mon Sep  6 22:47:44 2010
@@ -0,0 +1,173 @@
+/*
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ */
+
+package org.apache.cassandra.io.sstable;
+
+import java.io.File;
+import java.util.EnumSet;
+
+import com.google.common.base.Objects;
+
+import org.apache.cassandra.utils.Pair;
+
+/**
+ * SSTables are made up of multiple components in separate files. Components are
+ * identified by a type and an id, but required unique components (such as the Data
+ * and Index files) may have implicit ids assigned to them.
+ */
+public class Component
+{
+    final static EnumSet<Type> TYPES = EnumSet.allOf(Type.class);
+    enum Type
+    {
+        // the base data for an sstable: the remaining components can be regenerated
+        // based on the data component
+        DATA("Data.db"),
+        // index of the row keys with pointers to their positions in the data file
+        PRIMARY_INDEX("Index.db"),
+        // serialized bloom filter for the row keys in the sstable
+        FILTER("Filter.db"),
+        // 0-length file that is created when an sstable is ready to be deleted
+        COMPACTED_MARKER("Compacted"),
+        // statistical metadata about the content of the sstable
+        STATS("Statistics.db"),
+        // a bitmap secondary index: many of these may exist per sstable
+        BITMAP_INDEX("Bitidx.db");
+
+        final String repr;
+        Type(String repr)
+        {
+            this.repr = repr;
+        }
+        
+        static Type fromRepresentation(String repr)
+        {
+            for (Type type : TYPES)
+                if (repr.equals(type.repr))
+                    return type;
+            throw new RuntimeException("Invalid SSTable component: '" + repr + "'");
+        }
+    }
+
+    // singleton components for types that don't need ids
+    public final static Component DATA = new Component(Type.DATA, -1);
+    public final static Component PRIMARY_INDEX = new Component(Type.PRIMARY_INDEX, -1);
+    public final static Component FILTER = new Component(Type.FILTER, -1);
+    public final static Component COMPACTED_MARKER = new Component(Type.COMPACTED_MARKER, -1);
+    public final static Component STATS = new Component(Type.STATS, -1);
+
+    public final Type type;
+    public final int id;
+    public final int hashCode;
+
+    public Component(Type type)
+    {
+        this(type, -1);
+    }
+
+    public Component(Type type, int id)
+    {
+        this.type = type;
+        this.id = id;
+        this.hashCode = Objects.hashCode(type, id);
+    }
+
+    /**
+     * @return The unique (within an sstable) name for this component.
+     */
+    public String name()
+    {
+        switch(type)
+        {
+            case DATA:
+            case PRIMARY_INDEX:
+            case FILTER:
+            case COMPACTED_MARKER:
+            case STATS:
+                return type.repr;
+            case BITMAP_INDEX:
+                return String.format("%d-%s", id, type.repr);
+        }
+        throw new IllegalStateException();
+    }
+
+    /**
+     * Filename of the form "<ksname>/<cfname>-[tmp-][<version>-]<gen>-<component>",
+     * where <component> is of the form "[<id>-]<component>".
+     * @return A Descriptor for the SSTable, and a Component for this particular file.
+     * TODO move descriptor into Component field
+     */
+    public static Pair<Descriptor,Component> fromFilename(File directory, String name)
+    {
+        Pair<Descriptor,String> path = Descriptor.fromFilename(directory, name);
+
+        // parse the component suffix
+        String repr = path.right;
+        int id = -1;
+        int separatorPos = repr.indexOf('-');
+        if (separatorPos != -1)
+        {
+            id = Integer.parseInt(repr.substring(0, separatorPos));
+            repr = repr.substring(separatorPos+1, repr.length());
+        }
+        Type type = Type.fromRepresentation(repr);
+        // build (or retrieve singleton for) the component object
+        Component component;
+        switch(type)
+        {
+            case DATA:              component = Component.DATA;             break;
+            case PRIMARY_INDEX:     component = Component.PRIMARY_INDEX;    break;
+            case FILTER:            component = Component.FILTER;           break;
+            case COMPACTED_MARKER:  component = Component.COMPACTED_MARKER; break;
+            case STATS:             component = Component.STATS;            break;
+            case BITMAP_INDEX:
+                 component = new Component(type, id);
+                 break;
+            default:
+                 throw new IllegalStateException();
+        }
+
+        return new Pair<Descriptor,Component>(path.left, component);
+    }
+
+    @Override
+    public String toString()
+    {
+        return this.name();
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o == this)
+            return true;
+        if (!(o instanceof Component))
+            return false;
+        Component that = (Component)o;
+        return this.type == that.type && this.id == that.id;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return hashCode;
+    }
+}

Modified: cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Descriptor.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Descriptor.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Descriptor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/io/sstable/Descriptor.java Mon Sep  6 22:47:44 2010
@@ -26,6 +26,8 @@ import java.util.StringTokenizer;
 
 import com.google.common.base.Objects;
 
+import org.apache.cassandra.utils.Pair;
+
 /**
  * A SSTable is described by the keyspace and column family it contains data
  * for, a generation (where higher generations contain more recent data) and
@@ -76,6 +78,11 @@ public class Descriptor
         isLatestVersion = version.compareTo(CURRENT_VERSION) == 0;
     }
 
+    public String filenameFor(Component component)
+    {
+        return filenameFor(component.name());
+    }
+
     /**
      * @param suffix A component suffix, such as 'Data.db'/'Index.db'/etc
      * @return A filename for this descriptor with the given suffix.
@@ -95,9 +102,7 @@ public class Descriptor
     }
 
     /**
-     * Filename of the form "<ksname>/<cfname>-[tmp-][<version>-]<gen>-*"
-     * @param filename A full SSTable filename, including the directory.
-     * @return A SSTable.Descriptor for the filename.
+     * @see #fromFilename(directory, name)
      */
     public static Descriptor fromFilename(String filename)
     {
@@ -105,7 +110,15 @@ public class Descriptor
         assert separatorPos != -1 : "Filename must include parent directory.";
         File directory = new File(filename.substring(0, separatorPos));
         String name = filename.substring(separatorPos+1, filename.length());
+        return fromFilename(directory, name).left;
+    }
 
+    /**
+     * Filename of the form "<ksname>/<cfname>-[tmp-][<version>-]<gen>-<component>"
+     * @return A Descriptor for the SSTable, and the Component remainder.
+     */
+    static Pair<Descriptor,String> fromFilename(File directory, String name)
+    {
         // name of parent directory is keyspace name
         String ksname = directory.getName();
 
@@ -134,7 +147,10 @@ public class Descriptor
         }
         int generation = Integer.parseInt(nexttok);
 
-        return new Descriptor(version, directory, ksname, cfname, generation, temporary);
+        // component suffix
+        String component = st.nextToken();
+
+        return new Pair<Descriptor,String>(new Descriptor(version, directory, ksname, cfname, generation, temporary), component);
     }
 
     /**

Modified: cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTable.java Mon Sep  6 22:47:44 2010
@@ -20,11 +20,10 @@
 package org.apache.cassandra.io.sstable;
 
 import java.io.File;
+import java.io.FilenameFilter;
 import java.io.IOError;
 import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Arrays;
+import java.util.*;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,6 +32,7 @@ import org.apache.cassandra.config.CFMet
 import org.apache.cassandra.dht.IPartitioner;
 import org.apache.cassandra.io.util.FileUtils;
 import org.apache.cassandra.utils.EstimatedHistogram;
+import org.apache.cassandra.utils.Pair;
 
 /**
  * This class is built on top of the SequenceFile. It stores
@@ -50,31 +50,33 @@ public abstract class SSTable
 {
     static final Logger logger = LoggerFactory.getLogger(SSTable.class);
 
-    public static final String COMPONENT_DATA = "Data.db";
-    public static final String COMPONENT_INDEX = "Index.db";
-    public static final String COMPONENT_FILTER = "Filter.db";
-    public static final String COMPONENT_STATS = "Statistics.db";
+    // TODO: replace with 'Component' objects
+    public static final String COMPONENT_DATA = Component.Type.DATA.repr;
+    public static final String COMPONENT_INDEX = Component.Type.PRIMARY_INDEX.repr;
+    public static final String COMPONENT_FILTER = Component.Type.FILTER.repr;
+    public static final String COMPONENT_STATS = Component.Type.STATS.repr;
 
-    public static final String COMPONENT_COMPACTED = "Compacted";
+    public static final String COMPONENT_COMPACTED = Component.Type.COMPACTED_MARKER.repr;
 
     protected final Descriptor desc;
+    protected final Set<Component> components;
     public final CFMetaData metadata;
     protected final IPartitioner partitioner;
 
     public static final String TEMPFILE_MARKER = "tmp";
 
-    public static List<String> components = Collections.unmodifiableList(Arrays.asList(COMPONENT_FILTER, COMPONENT_INDEX, COMPONENT_DATA, COMPONENT_STATS));
     protected EstimatedHistogram estimatedRowSize = new EstimatedHistogram(150);
     protected EstimatedHistogram estimatedColumnCount = new EstimatedHistogram(114);
 
-    protected SSTable(String filename, CFMetaData metadata, IPartitioner partitioner)
+    protected SSTable(Descriptor desc, CFMetaData metadata, IPartitioner partitioner)
     {
-        this(Descriptor.fromFilename(filename), metadata, partitioner);
+        this(desc, new HashSet<Component>(), metadata, partitioner);
     }
 
-    protected SSTable(Descriptor desc, CFMetaData metadata, IPartitioner partitioner)
+    protected SSTable(Descriptor desc, Set<Component> components, CFMetaData metadata, IPartitioner partitioner)
     {
         this.desc = desc;
+        this.components = components;
         this.metadata = metadata;
         this.partitioner = partitioner;
     }
@@ -99,19 +101,9 @@ public abstract class SSTable
         return desc;
     }
 
-    public static String indexFilename(String dataFile)
-    {
-        return Descriptor.fromFilename(dataFile).filenameFor(COMPONENT_INDEX);
-    }
-
-    public String indexFilename()
-    {
-        return desc.filenameFor(COMPONENT_INDEX);
-    }
-
-    protected static String compactedFilename(String dataFile)
+    public Set<Component> getComponents()
     {
-        return Descriptor.fromFilename(dataFile).filenameFor(COMPONENT_COMPACTED);
+        return components;
     }
 
     /**
@@ -121,53 +113,36 @@ public abstract class SSTable
      * we write a marker to `compactedFilename` when a file is compacted;
      * if such a marker exists on startup, the file should be removed.
      *
+     * This method will also remove SSTables that are marked as temporary.
+     *
      * @return true if the file was deleted
      */
-    public static boolean deleteIfCompacted(String dataFilename)
+    public static boolean conditionalDelete(Descriptor desc, Set<Component> components)
     {
-        if (new File(compactedFilename(dataFilename)).exists())
+        if (!components.contains(Component.COMPACTED_MARKER) && !desc.temporary)
+            // not compacted or temporary
+            return false;
+        try
         {
-            try
+            // remove the DATA component first if it exists
+            if (components.contains(Component.DATA))
+                FileUtils.deleteWithConfirm(desc.filenameFor(Component.DATA));
+            for (Component component : components)
             {
-                FileUtils.deleteWithConfirm(new File(dataFilename));
-                FileUtils.deleteWithConfirm(new File(SSTable.indexFilename(dataFilename)));
-                FileUtils.deleteWithConfirm(new File(SSTable.filterFilename(dataFilename)));
-                FileUtils.deleteWithConfirm(new File(SSTable.statisticsFilename(dataFilename)));
-                FileUtils.deleteWithConfirm(new File(SSTable.compactedFilename(dataFilename)));
+                if (component.equals(Component.DATA) || component.equals(Component.COMPACTED_MARKER))
+                    continue;
+                FileUtils.deleteWithConfirm(desc.filenameFor(component));
             }
-            catch (IOException e)
-            {
-                throw new IOError(e);
-            }
-            logger.info("Deleted " + dataFilename);
-            return true;
+            // remove the COMPACTED_MARKER component last if it exists
+            if (components.contains(Component.COMPACTED_MARKER))
+                FileUtils.deleteWithConfirm(desc.filenameFor(Component.COMPACTED_MARKER));
         }
-        return false;
-    }
-
-    protected String compactedFilename()
-    {
-        return desc.filenameFor(COMPONENT_COMPACTED);
-    }
-
-    protected static String filterFilename(String dataFile)
-    {
-        return Descriptor.fromFilename(dataFile).filenameFor(COMPONENT_FILTER);
-    }
-
-    protected static String statisticsFilename(String dataFile)
-    {
-        return Descriptor.fromFilename(dataFile).filenameFor(COMPONENT_STATS);
-    }
-
-    public String filterFilename()
-    {
-        return desc.filenameFor(COMPONENT_FILTER);
-    }
-
-    public String statisticsFilename()
-    {
-        return desc.filenameFor(COMPONENT_STATS);
+        catch (IOException e)
+        {
+            throw new IOError(e);
+        }
+        logger.info("Deleted " + desc);
+        return true;
     }
 
     public String getFilename()
@@ -185,6 +160,41 @@ public abstract class SSTable
         return desc.ksname;
     }
 
+    /**
+     * @return A Descriptor,Component pair, or null if not a valid sstable component.
+     */
+    public static Pair<Descriptor,Component> tryComponentFromFilename(File dir, String name)
+    {
+        try
+        {
+            return Component.fromFilename(dir, name);
+        }
+        catch (Exception e)
+        {
+            logger.warn("Invalid file '{}' in data directory {}.", name, dir);
+            return null;
+        }
+    }
+
+    /**
+     * Discovers existing components for the descriptor. Slow: only intended for use outside the critical path.
+     */
+    static Set<Component> componentsFor(final Descriptor desc) throws IOException
+    {
+        final Set<Component> components = new HashSet<Component>();
+        desc.directory.list(new FilenameFilter()
+        {
+            public boolean accept(File dir, String name)
+            {
+                Pair<Descriptor,Component> component = tryComponentFromFilename(dir, name);
+                if (component != null && component.left.equals(desc))
+                    components.add(component.right);
+                return false;
+            }
+        });
+        return components;
+    }
+
     public static long getTotalBytes(Iterable<SSTableReader> sstables)
     {
         long sum = 0;
@@ -198,9 +208,9 @@ public abstract class SSTable
     public long bytesOnDisk()
     {
         long bytes = 0;
-        for (String cname : components)
+        for (Component component : components)
         {
-            bytes += new File(desc.filenameFor(cname)).length();
+            bytes += new File(desc.filenameFor(component)).length();
         }
         return bytes;
     }

Modified: cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java Mon Sep  6 22:47:44 2010
@@ -24,6 +24,7 @@ import java.io.IOError;
 import java.io.IOException;
 import java.lang.ref.PhantomReference;
 import java.lang.ref.ReferenceQueue;
+import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -31,6 +32,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.cassandra.io.DeletionService;
+import org.apache.cassandra.io.sstable.Component;
+import org.apache.cassandra.io.sstable.Descriptor;
 import org.apache.cassandra.io.util.FileUtils;
 
 public class SSTableDeletingReference extends PhantomReference<SSTableReader>
@@ -41,7 +44,8 @@ public class SSTableDeletingReference ex
     public static final int RETRY_DELAY = 10000;
 
     private final SSTableTracker tracker;
-    public final String path;
+    public final Descriptor desc;
+    public final Set<Component> components;
     private final long size;
     private boolean deleteOnCleanup;
 
@@ -49,7 +53,8 @@ public class SSTableDeletingReference ex
     {
         super(referent, q);
         this.tracker = tracker;
-        this.path = referent.getFilename();
+        this.desc = referent.getDescriptor();
+        this.components = referent.getComponents();
         this.size = referent.bytesOnDisk();
     }
 
@@ -63,9 +68,8 @@ public class SSTableDeletingReference ex
         if (deleteOnCleanup)
         {
             // this is tricky because the mmapping might not have been finalized yet,
-            // and delete will fail until it is.  additionally, we need to make sure to
+            // and delete will fail (on Windows) until it is.  additionally, we need to make sure to
             // delete the data file first, so on restart the others will be recognized as GCable
-            // even if the compaction marker gets deleted next.
             timer.schedule(new CleanupTask(), RETRY_DELAY);
         }
     }
@@ -77,7 +81,8 @@ public class SSTableDeletingReference ex
         @Override
         public void run()
         {
-            File datafile = new File(path);
+            // retry until we can successfully delete the DATA component: see above
+            File datafile = new File(desc.filenameFor(Component.DATA));
             if (!datafile.delete())
             {
                 if (attempts++ < DeletionService.MAX_RETRIES)
@@ -87,22 +92,13 @@ public class SSTableDeletingReference ex
                 }
                 else
                 {
-                    throw new RuntimeException("Unable to delete " + path);
+                    throw new RuntimeException("Unable to delete " + datafile);
                 }
             }
-            try
-            {
-                FileUtils.deleteWithConfirm(new File(SSTable.indexFilename(path)));
-                FileUtils.deleteWithConfirm(new File(SSTable.filterFilename(path)));
-                FileUtils.deleteWithConfirm(new File(SSTable.statisticsFilename(path)));
-                FileUtils.deleteWithConfirm(new File(SSTable.compactedFilename(path)));
-            }
-            catch (IOException e)
-            {
-                throw new IOError(e);
-            }
+            // let the remainder be cleaned up by conditionalDelete
+            components.remove(Component.DATA);
+            SSTable.conditionalDelete(desc, components);
             tracker.spaceReclaimed(size);
-            logger.info("Deleted " + path);
         }
     }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableReader.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableReader.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableReader.java Mon Sep  6 22:47:44 2010
@@ -86,7 +86,7 @@ public class SSTableReader extends SSTab
                     }
                     catch (IOException e)
                     {
-                        logger.error("Error deleting " + r.path, e);
+                        logger.error("Error deleting " + r.desc, e);
                     }
                 }
             }
@@ -155,36 +155,21 @@ public class SSTableReader extends SSTab
 
     public static SSTableReader open(Descriptor desc) throws IOException
     {
-        return open(desc, DatabaseDescriptor.getCFMetaData(desc.ksname, desc.cfname), StorageService.getPartitioner());
+        Set<Component> components = SSTable.componentsFor(desc);
+        return open(desc, components, DatabaseDescriptor.getCFMetaData(desc.ksname, desc.cfname), StorageService.getPartitioner());
     }
 
-    public static SSTableReader open(Descriptor descriptor, CFMetaData metadata, IPartitioner partitioner) throws IOException
+    public static SSTableReader open(Descriptor descriptor, Set<Component> components, CFMetaData metadata, IPartitioner partitioner) throws IOException
     {
         assert partitioner != null;
 
         long start = System.currentTimeMillis();
         logger.info("Sampling index for " + descriptor);
 
-        SSTableReader sstable;
-        // FIXME: version conditional readers here
-        if (true)
-        {
-            sstable = internalOpen(descriptor, metadata, partitioner);
-        }
-
-        if (logger.isDebugEnabled())
-            logger.debug("INDEX LOAD TIME for " + descriptor + ": " + (System.currentTimeMillis() - start) + " ms.");
-
-        return sstable;
-    }
-
-    /** Open a RowIndexedReader which needs its state loaded from disk. */
-    static SSTableReader internalOpen(Descriptor desc, CFMetaData metadata, IPartitioner partitioner) throws IOException
-    {
-        SSTableReader sstable = new SSTableReader(desc, metadata, partitioner, null, null, null, null, System.currentTimeMillis());
+        SSTableReader sstable = new SSTableReader(descriptor, components, metadata, partitioner, null, null, null, null, System.currentTimeMillis(), null, null);
 
         // versions before 'c' encoded keys as utf-16 before hashing to the filter
-        if (desc.hasStringsInBloomFilter)
+        if (descriptor.hasStringsInBloomFilter)
         {
             sstable.load(true);
         }
@@ -193,57 +178,40 @@ public class SSTableReader extends SSTab
             sstable.load(false);
             sstable.loadBloomFilter();
         }
-        sstable.loadStatistics(desc);
-
-        return sstable;
-    }
-
-    private SSTableReader(Descriptor desc,
-                          CFMetaData metadata,
-                          IPartitioner partitioner,
-                          SegmentedFile ifile,
-                          SegmentedFile dfile,
-                          IndexSummary indexSummary,
-                          BloomFilter bloomFilter,
-                          long maxDataAge)
-            throws IOException
-    {
-        super(desc, metadata, partitioner);
-        this.maxDataAge = maxDataAge;
+        sstable.loadStatistics(descriptor);
 
+        if (logger.isDebugEnabled())
+            logger.debug("INDEX LOAD TIME for " + descriptor + ": " + (System.currentTimeMillis() - start) + " ms.");
 
-        this.ifile = ifile;
-        this.dfile = dfile;
-        this.indexSummary = indexSummary;
-        this.bf = bloomFilter;
+        return sstable;
     }
 
     /**
      * Open a RowIndexedReader which already has its state initialized (by SSTableWriter).
      */
-    static SSTableReader internalOpen(Descriptor desc, CFMetaData metadata, IPartitioner partitioner, SegmentedFile ifile, SegmentedFile dfile, IndexSummary isummary, BloomFilter bf, long maxDataAge, EstimatedHistogram rowsize,
+    static SSTableReader internalOpen(Descriptor desc, Set<Component> components, CFMetaData metadata, IPartitioner partitioner, SegmentedFile ifile, SegmentedFile dfile, IndexSummary isummary, BloomFilter bf, long maxDataAge, EstimatedHistogram rowsize,
                                       EstimatedHistogram columncount) throws IOException
     {
         assert desc != null && partitioner != null && ifile != null && dfile != null && isummary != null && bf != null;
-        return new SSTableReader(desc, metadata, partitioner, ifile, dfile, isummary, bf, maxDataAge, rowsize, columncount);
+        return new SSTableReader(desc, components, metadata, partitioner, ifile, dfile, isummary, bf, maxDataAge, rowsize, columncount);
     }
 
-    SSTableReader(Descriptor desc,
-                  CFMetaData metadata,
-                  IPartitioner partitioner,
-                  SegmentedFile ifile,
-                  SegmentedFile dfile,
-                  IndexSummary indexSummary,
-                  BloomFilter bloomFilter,
-                  long maxDataAge,
-                  EstimatedHistogram rowsize,
-                  EstimatedHistogram columncount)
+    private SSTableReader(Descriptor desc,
+                          Set<Component> components,
+                          CFMetaData metadata,
+                          IPartitioner partitioner,
+                          SegmentedFile ifile,
+                          SegmentedFile dfile,
+                          IndexSummary indexSummary,
+                          BloomFilter bloomFilter,
+                          long maxDataAge,
+                          EstimatedHistogram rowsize,
+                          EstimatedHistogram columncount)
     throws IOException
     {
-        super(desc, metadata, partitioner);
+        super(desc, components, metadata, partitioner);
         this.maxDataAge = maxDataAge;
 
-
         this.ifile = ifile;
         this.dfile = dfile;
         this.indexSummary = indexSummary;
@@ -261,7 +229,7 @@ public class SSTableReader extends SSTab
 
     void loadBloomFilter() throws IOException
     {
-        DataInputStream stream = new DataInputStream(new FileInputStream(filterFilename()));
+        DataInputStream stream = new DataInputStream(new FileInputStream(desc.filenameFor(Component.FILTER)));
         try
         {
             bf = BloomFilter.serializer().deserialize(stream);
@@ -282,7 +250,7 @@ public class SSTableReader extends SSTab
 
         // we read the positions in a BRAF so we don't have to worry about an entry spanning a mmap boundary.
         indexSummary = new IndexSummary();
-        BufferedRandomAccessFile input = new BufferedRandomAccessFile(indexFilename(), "r");
+        BufferedRandomAccessFile input = new BufferedRandomAccessFile(desc.filenameFor(Component.PRIMARY_INDEX), "r");
         try
         {
             long indexSize = input.length();
@@ -313,8 +281,8 @@ public class SSTableReader extends SSTab
 
         // finalize the state of the reader
         indexSummary.complete();
-        ifile = ibuilder.complete(indexFilename());
-        dfile = dbuilder.complete(getFilename());
+        ifile = ibuilder.complete(desc.filenameFor(Component.PRIMARY_INDEX));
+        dfile = dbuilder.complete(desc.filenameFor(Component.DATA));
     }
 
     /** get the position in the index file to start scanning to find the given key (at most indexInterval keys away) */
@@ -503,7 +471,7 @@ public class SSTableReader extends SSTab
             logger.debug("Marking " + getFilename() + " compacted");
         try
         {
-            if (!new File(compactedFilename()).createNewFile())
+            if (!new File(desc.filenameFor(Component.COMPACTED_MARKER)).createNewFile())
                 throw new IOException("Unable to create compaction marker");
         }
         catch (IOException e)

Modified: cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java Mon Sep  6 22:47:44 2010
@@ -55,10 +55,16 @@ public class SSTableWriter extends SSTab
 
     public SSTableWriter(String filename, long keyCount, CFMetaData metadata, IPartitioner partitioner) throws IOException
     {
-        super(filename, metadata, partitioner);
+        super(Descriptor.fromFilename(filename), metadata, partitioner);
         iwriter = new IndexWriter(desc, partitioner, keyCount);
         dbuilder = SegmentedFile.getBuilder(DatabaseDescriptor.getDiskAccessMode());
         dataFile = new BufferedRandomAccessFile(getFilename(), "rw", DatabaseDescriptor.getInMemoryCompactionLimit());
+
+        // the set of required components
+        components.add(Component.DATA);
+        components.add(Component.FILTER);
+        components.add(Component.PRIMARY_INDEX);
+        components.add(Component.STATS);
     }
 
     private long beforeAppend(DecoratedKey decoratedKey) throws IOException
@@ -144,13 +150,13 @@ public class SSTableWriter extends SSTab
         writeStatistics(desc);
 
         // remove the 'tmp' marker from all components
-        final Descriptor newdesc = rename(desc);
+        final Descriptor newdesc = rename(desc, components);
 
 
         // finalize in-memory state for the reader
         SegmentedFile ifile = iwriter.builder.complete(newdesc.filenameFor(SSTable.COMPONENT_INDEX));
         SegmentedFile dfile = dbuilder.complete(newdesc.filenameFor(SSTable.COMPONENT_DATA));
-        SSTableReader sstable = SSTableReader.internalOpen(newdesc, metadata, partitioner, ifile, dfile, iwriter.summary, iwriter.bf, maxDataAge, estimatedRowSize, estimatedColumnCount);
+        SSTableReader sstable = SSTableReader.internalOpen(newdesc, components, metadata, partitioner, ifile, dfile, iwriter.summary, iwriter.bf, maxDataAge, estimatedRowSize, estimatedColumnCount);
         iwriter = null;
         dbuilder = null;
         return sstable;
@@ -164,12 +170,12 @@ public class SSTableWriter extends SSTab
         dos.close();
     }
 
-    static Descriptor rename(Descriptor tmpdesc)
+    static Descriptor rename(Descriptor tmpdesc, Set<Component> components)
     {
         Descriptor newdesc = tmpdesc.asTemporary(false);
         try
         {
-            for (String component : components)
+            for (Component component : components)
                 FBUtilities.renameWithConfirm(tmpdesc.filenameFor(component), newdesc.filenameFor(component));
         }
         catch (IOException e)
@@ -326,8 +332,10 @@ public class SSTableWriter extends SSTab
             throw new RuntimeException(String.format("Cannot recover SSTable with version %s (current version %s).",
                                                      desc.version, Descriptor.CURRENT_VERSION));
 
+        // FIXME: once maybeRecover is recovering BMIs, it should return the recovered
+        // components
         maybeRecover(desc);
-        return SSTableReader.open(rename(desc));
+        return SSTableReader.open(rename(desc, SSTable.componentsFor(desc)));
     }
 
     /**

Modified: cassandra/trunk/src/java/org/apache/cassandra/io/util/FileUtils.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/io/util/FileUtils.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/io/util/FileUtils.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/io/util/FileUtils.java Mon Sep  6 22:47:44 2010
@@ -38,6 +38,11 @@ public class FileUtils
     private static final double gb_ = 1024*1024*1024d;
     private static final double tb_ = 1024*1024*1024*1024d;
 
+    public static void deleteWithConfirm(String file) throws IOException
+    {
+        deleteWithConfirm(new File(file));
+    }
+
     public static void deleteWithConfirm(File file) throws IOException
     {
         assert file.exists() : "attempted to delete non-existing file " + file.getName();

Modified: cassandra/trunk/src/java/org/apache/cassandra/tools/SSTableExport.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/tools/SSTableExport.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/tools/SSTableExport.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/tools/SSTableExport.java Mon Sep  6 22:47:44 2010
@@ -31,6 +31,7 @@ import org.apache.cassandra.db.IColumn;
 import org.apache.cassandra.db.TimestampClock;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.dht.IPartitioner;
+import org.apache.cassandra.io.sstable.Component;
 import org.apache.cassandra.io.sstable.Descriptor;
 import org.apache.cassandra.io.sstable.SSTable;
 import org.apache.cassandra.io.sstable.SSTableIdentityIterator;
@@ -159,7 +160,7 @@ public class SSTableExport
     {
         IPartitioner partitioner = StorageService.getPartitioner();
         Descriptor desc = Descriptor.fromFilename(ssTableFile);
-        BufferedRandomAccessFile input = new BufferedRandomAccessFile(SSTable.indexFilename(ssTableFile), "r");
+        BufferedRandomAccessFile input = new BufferedRandomAccessFile(desc.filenameFor(Component.PRIMARY_INDEX), "r");
         while (!input.isEOF())
         {
             DecoratedKey decoratedKey = SSTableReader.decodeKey(partitioner,

Modified: cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java Mon Sep  6 22:47:44 2010
@@ -91,8 +91,8 @@ public class SSTableUtils
             sortedEntries.put(writer.partitioner.decorateKey(entry.getKey()), entry.getValue());
         for (Map.Entry<DecoratedKey, byte[]> entry : sortedEntries.entrySet())
             writer.append(entry.getKey(), entry.getValue());
-        new File(writer.indexFilename()).deleteOnExit();
-        new File(writer.filterFilename()).deleteOnExit();
+        new File(writer.desc.filenameFor(Component.PRIMARY_INDEX)).deleteOnExit();
+        new File(writer.desc.filenameFor(Component.FILTER)).deleteOnExit();
         return writer.closeAndOpenReader();
     }
 

Modified: cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java?rev=993171&r1=993170&r2=993171&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java Mon Sep  6 22:47:44 2010
@@ -80,8 +80,8 @@ public class SSTableWriterTest extends C
         
         SSTableReader orig = SSTableUtils.writeRawSSTable("Keyspace1", "Indexed1", entries);        
         // whack the index to trigger the recover
-        new File(orig.indexFilename()).delete();
-        new File(orig.filterFilename()).delete();
+        new File(orig.desc.filenameFor(Component.PRIMARY_INDEX)).delete();
+        new File(orig.desc.filenameFor(Component.FILTER)).delete();
         
         SSTableReader sstr = SSTableWriter.recoverAndOpen(orig.desc);
         



Mime
View raw message