diff --git a/src/java/org/apache/cassandra/db/BinaryMemtable.java b/src/java/org/apache/cassandra/db/BinaryMemtable.java index 0b8ac98258..a1bbe1223c 100644 --- a/src/java/org/apache/cassandra/db/BinaryMemtable.java +++ b/src/java/org/apache/cassandra/db/BinaryMemtable.java @@ -28,8 +28,6 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import org.apache.cassandra.config.DatabaseDescriptor; -import org.apache.cassandra.utils.BloomFilter; import org.apache.cassandra.io.SSTable; import org.apache.cassandra.service.StorageService; @@ -137,16 +135,14 @@ public class BinaryMemtable { if ( columnFamilies_.size() == 0 ) return; - ColumnFamilyStore cfStore = Table.open(table_).getColumnFamilyStore(cfName_); - String directory = DatabaseDescriptor.getDataFileLocation(); - String filename = cfStore.getTempFileName(); /* * Use the SSTable to write the contents of the TreeMap * to disk. */ + ColumnFamilyStore cfStore = Table.open(table_).getColumnFamilyStore(cfName_); List keys = new ArrayList( columnFamilies_.keySet() ); - SSTable ssTable = new SSTable(directory, filename, keys.size(), StorageService.getPartitioner()); + SSTable ssTable = new SSTable(cfStore.getTempSSTablePath(), keys.size(), StorageService.getPartitioner()); Collections.sort(keys); /* Use this BloomFilter to decide if a key exists in a SSTable */ for ( String key : keys ) diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java index fcee6e26b7..cb99e7e110 100644 --- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java +++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java @@ -358,13 +358,22 @@ public final class ColumnFamilyStore implements ColumnFamilyStoreMBean } /* - * Return a temporary file name. + * @return a temporary file name for an sstable. + * When the sstable object is closed, it will be renamed to a non-temporary + * format, so incomplete sstables can be recognized and removed on startup. */ - String getTempFileName() + String getTempSSTablePath() + { + // increment twice so that we do not generate consecutive numbers + String fname = getTempSSTableFileName(); + return new File(DatabaseDescriptor.getDataFileLocation(), fname).getAbsolutePath(); + } + + String getTempSSTableFileName() { - // Psuedo increment so that we do not generate consecutive numbers fileIndexGenerator_.incrementAndGet(); - return table_ + "-" + columnFamily_ + "-" + SSTable.temporaryFile_ + "-" + fileIndexGenerator_.incrementAndGet(); + return String.format("%s-%s-%s-%s-Data.db", + table_, columnFamily_, SSTable.temporaryFile_, fileIndexGenerator_.incrementAndGet()); } /* @@ -388,7 +397,8 @@ public final class ColumnFamilyStore implements ColumnFamilyStoreMBean index = lowestIndex + 1; - return table_ + "-" + columnFamily_ + "-" + SSTable.temporaryFile_ + "-" + index; + return String.format("%s-%s-%s-%s-Data.db", + table_, columnFamily_, SSTable.temporaryFile_, index); } void switchMemtable() @@ -1036,7 +1046,7 @@ public final class ColumnFamilyStore implements ColumnFamilyStoreMBean return result; } - mergedFileName = getTempFileName(); + mergedFileName = getTempSSTableFileName(); SSTable ssTableRange = null; String lastkey = null; List lfs = new ArrayList(); @@ -1115,7 +1125,8 @@ public final class ColumnFamilyStore implements ColumnFamilyStoreMBean rangeFileLocation = rangeFileLocation + System.getProperty("file.separator") + "bootstrap"; } FileUtils.createDirectory(rangeFileLocation); - ssTableRange = new SSTable(rangeFileLocation, mergedFileName, expectedBloomFilterSize, StorageService.getPartitioner()); + String fname = new File(rangeFileLocation, mergedFileName).getAbsolutePath(); + ssTableRange = new SSTable(fname, expectedBloomFilterSize, StorageService.getPartitioner()); } try { @@ -1304,7 +1315,8 @@ public final class ColumnFamilyStore implements ColumnFamilyStoreMBean if (ssTable == null) { - ssTable = new SSTable(compactionFileLocation, mergedFileName, expectedBloomFilterSize, StorageService.getPartitioner()); + String fname = new File(compactionFileLocation, mergedFileName).getAbsolutePath(); + ssTable = new SSTable(fname, expectedBloomFilterSize, StorageService.getPartitioner()); } ssTable.append(lastkey, bufOut); totalkeysWritten++; diff --git a/src/java/org/apache/cassandra/db/Memtable.java b/src/java/org/apache/cassandra/db/Memtable.java index c117a248d9..7ec8b0cb61 100644 --- a/src/java/org/apache/cassandra/db/Memtable.java +++ b/src/java/org/apache/cassandra/db/Memtable.java @@ -31,7 +31,6 @@ import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.io.DataOutputBuffer; import org.apache.cassandra.io.SSTable; import org.apache.cassandra.service.StorageService; -import org.apache.cassandra.utils.BloomFilter; import org.apache.cassandra.utils.DestructivePQIterator; import org.apache.log4j.Logger; @@ -251,9 +250,7 @@ public class Memtable implements Comparable logger_.info("Flushing " + this); ColumnFamilyStore cfStore = Table.open(table_).getColumnFamilyStore(cfName_); - String directory = DatabaseDescriptor.getDataFileLocation(); - String filename = cfStore.getTempFileName(); - SSTable ssTable = new SSTable(directory, filename, columnFamilies_.size(), StorageService.getPartitioner()); + SSTable ssTable = new SSTable(cfStore.getTempSSTablePath(), columnFamilies_.size(), StorageService.getPartitioner()); // sort keys in the order they would be in when decorated final IPartitioner partitioner = StorageService.getPartitioner(); diff --git a/src/java/org/apache/cassandra/io/SSTable.java b/src/java/org/apache/cassandra/io/SSTable.java index a5d2995b25..17a9a6c3a0 100644 --- a/src/java/org/apache/cassandra/io/SSTable.java +++ b/src/java/org/apache/cassandra/io/SSTable.java @@ -132,12 +132,14 @@ public class SSTable private SSTable(String filename, IPartitioner partitioner) { + assert filename.endsWith("-Data.db"); dataFile_ = filename; partitioner_ = partitioner; } - private SSTable(String filename, int keyCount, IPartitioner partitioner) throws IOException + public SSTable(String filename, int keyCount, IPartitioner partitioner) throws IOException { + assert filename.endsWith("-Data.db"); dataFile_ = filename; partitioner_ = partitioner; dataWriter_ = SequenceFile.bufferedWriter(dataFile_, 4 * 1024 * 1024); @@ -145,15 +147,6 @@ public class SSTable bf = new BloomFilter(keyCount, 15); } - /** - * This ctor is used for writing data into the SSTable. Use this - * version for non DB writes to the SSTable. - */ - public SSTable(String directory, String filename, int keyCount, IPartitioner partitioner) throws IOException - { - this(directory + System.getProperty("file.separator") + filename + "-Data.db", keyCount, partitioner); - } - static String parseTableName(String filename) { String[] parts = new File(filename).getName().split("-"); // table, cf, index, [filetype] diff --git a/test/unit/org/apache/cassandra/db/CompactionsTest.java b/test/unit/org/apache/cassandra/db/CompactionsTest.java index 4043ab775a..d015887ec4 100644 --- a/test/unit/org/apache/cassandra/db/CompactionsTest.java +++ b/test/unit/org/apache/cassandra/db/CompactionsTest.java @@ -28,9 +28,10 @@ import java.util.Arrays; import org.junit.Test; import org.apache.cassandra.io.SSTable; +import org.apache.cassandra.CleanupHelper; import static junit.framework.Assert.assertEquals; -public class CompactionsTest +public class CompactionsTest extends CleanupHelper { @Test public void testCompactions() throws IOException, ExecutionException, InterruptedException diff --git a/test/unit/org/apache/cassandra/io/SSTableTest.java b/test/unit/org/apache/cassandra/io/SSTableTest.java index 182b8c1eb0..f67e4ecb48 100644 --- a/test/unit/org/apache/cassandra/io/SSTableTest.java +++ b/test/unit/org/apache/cassandra/io/SSTableTest.java @@ -32,10 +32,10 @@ public class SSTableTest extends CleanupHelper { @Test public void testSingleWrite() throws IOException { - File f = File.createTempFile("sstable", "-" + SSTable.temporaryFile_); + File f = tempSSTableFileName(); // write test data - SSTable ssTable = new SSTable(f.getParent(), f.getName(), 1, new OrderPreservingPartitioner()); + SSTable ssTable = new SSTable(f.getAbsolutePath(), 1, new OrderPreservingPartitioner()); Random random = new Random(); byte[] bytes = new byte[1024]; random.nextBytes(bytes); @@ -50,6 +50,11 @@ public class SSTableTest extends CleanupHelper verifySingle(ssTable, bytes, key); } + private File tempSSTableFileName() throws IOException + { + return File.createTempFile("sstable", "-" + SSTable.temporaryFile_ + "-Data.db"); + } + private void verifySingle(SSTable sstable, byte[] bytes, String key) throws IOException { FileStruct fs = sstable.getFileStruct(); @@ -62,7 +67,7 @@ public class SSTableTest extends CleanupHelper @Test public void testManyWrites() throws IOException { - File f = File.createTempFile("sstable", "-" + SSTable.temporaryFile_); + File f = tempSSTableFileName(); TreeMap map = new TreeMap(); for ( int i = 100; i < 1000; ++i ) @@ -71,7 +76,7 @@ public class SSTableTest extends CleanupHelper } // write - SSTable ssTable = new SSTable(f.getParent(), f.getName(), 1000, new OrderPreservingPartitioner()); + SSTable ssTable = new SSTable(f.getAbsolutePath(), 1000, new OrderPreservingPartitioner()); for (String key: map.navigableKeySet()) { ssTable.append(key, map.get(key));