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