You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by yu...@apache.org on 2014/07/07 17:53:44 UTC
git commit: Shorten SSTable path
Repository: cassandra
Updated Branches:
refs/heads/trunk 0ae5def83 -> d13a996e4
Shorten SSTable path
patch by yukim; reviewed by Josh McKenzie for CASSANDRA-6962
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/d13a996e
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/d13a996e
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/d13a996e
Branch: refs/heads/trunk
Commit: d13a996e45a3294a7c16102bf9d3da881ae2c732
Parents: 0ae5def
Author: Yuki Morishita <yu...@apache.org>
Authored: Mon Jul 7 10:53:01 2014 -0500
Committer: Yuki Morishita <yu...@apache.org>
Committed: Mon Jul 7 10:53:01 2014 -0500
----------------------------------------------------------------------
CHANGES.txt | 1 +
NEWS.txt | 7 ++
.../org/apache/cassandra/db/Directories.java | 64 +++++++---
.../db/compaction/CompactionManager.java | 2 +-
.../db/compaction/CompactionManagerMBean.java | 3 +-
.../apache/cassandra/io/sstable/Descriptor.java | 102 ++++++++++++----
.../apache/cassandra/io/sstable/SSTable.java | 9 +-
.../apache/cassandra/db/DirectoriesTest.java | 2 +-
.../db/compaction/CompactionsTest.java | 2 +-
.../cassandra/io/sstable/DescriptorTest.java | 120 +++++++++++++++++++
.../cassandra/io/sstable/SSTableUtils.java | 8 +-
11 files changed, 265 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index e80ab9f..5cbf4bb 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,6 +9,7 @@
* Make incremental repair default (CASSANDRA-7250)
* Enable code coverage thru JaCoCo (CASSANDRA-7226)
* Switch external naming of 'column families' to 'tables' (CASSANDRA-4369)
+ * Shorten SSTable path (CASSANDRA-6962)
2.1.1
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index 232cdf7..b51faec 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -16,6 +16,13 @@ using the provided 'sstableupgrade' tool.
3.0
===
+New features
+------------
+ - SSTable file name is changed. Now you don't have Keyspace/CF name
+ in file name. Also, secondary index has its own directory under parent's
+ directory.
+
+
Upgrading
---------
- CQL2 has been removed entirely in this release (previously deprecated
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/src/java/org/apache/cassandra/db/Directories.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Directories.java b/src/java/org/apache/cassandra/db/Directories.java
index 4319481..d62ebeb 100644
--- a/src/java/org/apache/cassandra/db/Directories.java
+++ b/src/java/org/apache/cassandra/db/Directories.java
@@ -191,7 +191,15 @@ public class Directories
String cfId = ByteBufferUtil.bytesToHex(ByteBufferUtil.bytes(metadata.cfId));
int idx = metadata.cfName.indexOf(SECONDARY_INDEX_NAME_SEPARATOR);
// secondary indicies go in the same directory as the base cf
- String directoryName = idx > 0 ? metadata.cfName.substring(0, idx) + "-" + cfId : metadata.cfName + "-" + cfId;
+ String directoryName;
+ if (idx >= 0)
+ {
+ directoryName = metadata.cfName.substring(0, idx) + "-" + cfId + File.separator + metadata.cfName.substring(idx);
+ }
+ else
+ {
+ directoryName = metadata.cfName + "-" + cfId;
+ }
this.dataPaths = new File[dataDirectories.length];
// If upgraded from version less than 2.1, use existing directories
@@ -318,7 +326,19 @@ public class Directories
public static File getSnapshotDirectory(Descriptor desc, String snapshotName)
{
- return getOrCreate(desc.directory, SNAPSHOT_SUBDIR, snapshotName);
+ return getSnapshotDirectory(desc.directory, snapshotName);
+ }
+
+ public static File getSnapshotDirectory(File location, String snapshotName)
+ {
+ if (location.getName().startsWith(SECONDARY_INDEX_NAME_SEPARATOR))
+ {
+ return getOrCreate(location.getParentFile(), SNAPSHOT_SUBDIR, snapshotName, location.getName());
+ }
+ else
+ {
+ return getOrCreate(location, SNAPSHOT_SUBDIR, snapshotName);
+ }
}
public File getSnapshotManifestFile(String snapshotName)
@@ -328,7 +348,19 @@ public class Directories
public static File getBackupsDirectory(Descriptor desc)
{
- return getOrCreate(desc.directory, BACKUPS_SUBDIR);
+ return getBackupsDirectory(desc.directory);
+ }
+
+ public static File getBackupsDirectory(File location)
+ {
+ if (location.getName().startsWith(SECONDARY_INDEX_NAME_SEPARATOR))
+ {
+ return getOrCreate(location.getParentFile(), BACKUPS_SUBDIR, location.getName());
+ }
+ else
+ {
+ return getOrCreate(location, BACKUPS_SUBDIR);
+ }
}
public SSTableLister sstableLister()
@@ -439,7 +471,7 @@ public class Directories
if (snapshotName != null)
{
- new File(location, join(SNAPSHOT_SUBDIR, snapshotName)).listFiles(getFilter());
+ getSnapshotDirectory(location, snapshotName).listFiles(getFilter());
continue;
}
@@ -447,28 +479,29 @@ public class Directories
location.listFiles(getFilter());
if (includeBackups)
- new File(location, BACKUPS_SUBDIR).listFiles(getFilter());
+ getBackupsDirectory(location).listFiles(getFilter());
}
filtered = true;
}
private FileFilter getFilter()
{
- // Note: the prefix needs to include cfname + separator to distinguish between a cfs and it's secondary indexes
- final String sstablePrefix = getSSTablePrefix();
return new FileFilter()
{
// This function always return false since accepts adds to the components map
public boolean accept(File file)
{
- // we are only interested in the SSTable files that belong to the specific ColumnFamily
- if (file.isDirectory() || !file.getName().startsWith(sstablePrefix))
+ if (file.isDirectory())
return false;
Pair<Descriptor, Component> pair = SSTable.tryComponentFromFilename(file.getParentFile(), file.getName());
if (pair == null)
return false;
+ // we are only interested in the SSTable files that belong to the specific ColumnFamily
+ if (!pair.left.ksname.equals(metadata.ksName) || !pair.left.cfname.equals(metadata.cfName))
+ return false;
+
if (skipTemporary && pair.left.type.isTemporary)
return false;
@@ -569,11 +602,6 @@ public class Directories
return result;
}
- private String getSSTablePrefix()
- {
- return metadata.ksName + Component.separator + metadata.cfName + Component.separator;
- }
-
public long getTrueAllocatedSizeIn(File input)
{
if (!input.isDirectory())
@@ -662,7 +690,6 @@ public class Directories
private final AtomicLong size = new AtomicLong(0);
private final Set<String> visited = newHashSet(); //count each file only once
private final Set<String> alive;
- private final String prefix = getSSTablePrefix();
public TrueFilesSizeVisitor()
{
@@ -675,8 +702,11 @@ public class Directories
private boolean isAcceptable(Path file)
{
- String fileName = file.toFile().getName();
- return fileName.startsWith(prefix)
+ String fileName = file.toFile().getName();
+ Pair<Descriptor, Component> pair = SSTable.tryComponentFromFilename(file.getParent().toFile(), fileName);
+ return pair != null
+ && pair.left.ksname.equals(metadata.ksName)
+ && pair.left.cfname.equals(metadata.cfName)
&& !visited.contains(fileName)
&& !alive.contains(fileName);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/src/java/org/apache/cassandra/db/compaction/CompactionManager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/compaction/CompactionManager.java b/src/java/org/apache/cassandra/db/compaction/CompactionManager.java
index 0f38e53..d571814 100644
--- a/src/java/org/apache/cassandra/db/compaction/CompactionManager.java
+++ b/src/java/org/apache/cassandra/db/compaction/CompactionManager.java
@@ -479,7 +479,7 @@ public class CompactionManager implements CompactionManagerMBean
}
// group by keyspace/columnfamily
ColumnFamilyStore cfs = Keyspace.open(desc.ksname).getColumnFamilyStore(desc.cfname);
- descriptors.put(cfs, cfs.directories.find(filename.trim()));
+ descriptors.put(cfs, cfs.directories.find(new File(filename.trim()).getName()));
}
List<Future<?>> futures = new ArrayList<>();
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/src/java/org/apache/cassandra/db/compaction/CompactionManagerMBean.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/compaction/CompactionManagerMBean.java b/src/java/org/apache/cassandra/db/compaction/CompactionManagerMBean.java
index acf1e52..6900b9f 100644
--- a/src/java/org/apache/cassandra/db/compaction/CompactionManagerMBean.java
+++ b/src/java/org/apache/cassandra/db/compaction/CompactionManagerMBean.java
@@ -66,7 +66,8 @@ public interface CompactionManagerMBean
* If you do so, user defined compaction is performed several times to the groups of files
* in the same keyspace/columnfamily.
*
- * @param dataFiles a comma separated list of sstable filename to compact
+ * @param dataFiles a comma separated list of sstable file to compact.
+ * must contain keyspace and columnfamily name in path(for 2.1+) or file name itself.
*/
public void forceUserDefinedCompaction(String dataFiles);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/src/java/org/apache/cassandra/io/sstable/Descriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/Descriptor.java b/src/java/org/apache/cassandra/io/sstable/Descriptor.java
index 4415db4..db5b60c 100644
--- a/src/java/org/apache/cassandra/io/sstable/Descriptor.java
+++ b/src/java/org/apache/cassandra/io/sstable/Descriptor.java
@@ -18,10 +18,13 @@
package org.apache.cassandra.io.sstable;
import java.io.File;
+import java.util.ArrayDeque;
+import java.util.Deque;
import java.util.StringTokenizer;
import com.google.common.base.Objects;
+import org.apache.cassandra.db.Directories;
import org.apache.cassandra.io.sstable.metadata.IMetadataSerializer;
import org.apache.cassandra.io.sstable.metadata.LegacyMetadataSerializer;
import org.apache.cassandra.io.sstable.metadata.MetadataSerializer;
@@ -60,6 +63,7 @@ public class Descriptor
// jb (2.0.1): switch from crc32 to adler32 for compression checksums
// checksum the compressed data
// ka (2.1.0): new Statistics.db file format
+ // new file name format
// index summaries can be downsampled and the sampling level is persisted
// switch uncompressed checksums to adler32
// tracks presense of legacy (local and remote) counter shards
@@ -75,6 +79,7 @@ public class Descriptor
public final boolean hasAllAdlerChecksums;
public final boolean hasRepairedAt;
public final boolean tracksLegacyCounterShards;
+ public final boolean newFileName;
public Version(String version)
{
@@ -86,6 +91,7 @@ public class Descriptor
hasAllAdlerChecksums = version.compareTo("ka") >= 0;
hasRepairedAt = version.compareTo("ka") >= 0;
tracksLegacyCounterShards = version.compareTo("ka") >= 0;
+ newFileName = version.compareTo("ka") >= 0;
}
/**
@@ -188,8 +194,11 @@ public class Descriptor
private void appendFileName(StringBuilder buff)
{
- buff.append(ksname).append(separator);
- buff.append(cfname).append(separator);
+ if (!version.newFileName)
+ {
+ buff.append(ksname).append(separator);
+ buff.append(cfname).append(separator);
+ }
if (type.isTemporary)
buff.append(type.marker).append(separator);
buff.append(version).append(separator);
@@ -230,13 +239,20 @@ public class Descriptor
return fromFilename(file.getParentFile(), file.getName(), skipComponent).left;
}
- public static Pair<Descriptor,String> fromFilename(File directory, String name)
+ public static Pair<Descriptor, String> fromFilename(File directory, String name)
{
return fromFilename(directory, name, false);
}
/**
- * Filename of the form "<ksname>-<cfname>-[tmp-][<version>-]<gen>-<component>"
+ * Filename of the form is vary by version:
+ *
+ * <ul>
+ * <li><ksname>-<cfname>-(tmp-)?<version>-<gen>-<component> for cassandra 2.0 and before</li>
+ * <li>(<tmp marker>-)?<version>-<gen>-<component> for cassandra 2.1 and later</li>
+ * </ul>
+ *
+ * If this is for SSTable of secondary index, directory should ends with index name for 2.1+.
*
* @param directory The directory of the SSTable files
* @param name The name of the SSTable file
@@ -244,43 +260,79 @@ public class Descriptor
*
* @return A Descriptor for the SSTable, and the Component remainder.
*/
- public static Pair<Descriptor,String> fromFilename(File directory, String name, boolean skipComponent)
+ public static Pair<Descriptor, String> fromFilename(File directory, String name, boolean skipComponent)
{
+ File parentDirectory = directory != null ? directory : new File(".");
+
// tokenize the filename
StringTokenizer st = new StringTokenizer(name, String.valueOf(separator));
String nexttok;
- // all filenames must start with keyspace and column family
- String ksname = st.nextToken();
- String cfname = st.nextToken();
+ // read tokens backwards to determine version
+ Deque<String> tokenStack = new ArrayDeque<>();
+ while (st.hasMoreTokens())
+ {
+ tokenStack.push(st.nextToken());
+ }
+
+ // component suffix
+ String component = skipComponent ? null : tokenStack.pop();
+
+ // generation
+ int generation = Integer.parseInt(tokenStack.pop());
+
+ // version
+ nexttok = tokenStack.pop();
+ if (!Version.validate(nexttok))
+ throw new UnsupportedOperationException("SSTable " + name + " is too old to open. Upgrade to 2.0 first, and run upgradesstables");
+ Version version = new Version(nexttok);
// optional temporary marker
- nexttok = st.nextToken();
Type type = Type.FINAL;
- if (nexttok.equals(Type.TEMP.marker))
+ nexttok = tokenStack.peek();
+ if (Type.TEMP.marker.equals(nexttok))
{
type = Type.TEMP;
- nexttok = st.nextToken();
+ tokenStack.pop();
}
- else if (nexttok.equals(Type.TEMPLINK.marker))
+ else if (Type.TEMPLINK.marker.equals(nexttok))
{
type = Type.TEMPLINK;
- nexttok = st.nextToken();
+ tokenStack.pop();
}
- if (!Version.validate(nexttok))
- throw new UnsupportedOperationException("SSTable " + name + " is too old to open. Upgrade to 2.0 first, and run upgradesstables");
- Version version = new Version(nexttok);
-
- nexttok = st.nextToken();
- int generation = Integer.parseInt(nexttok);
+ // ks/cf names
+ String ksname, cfname;
+ if (version.newFileName)
+ {
+ // for 2.1+ read ks and cf names from directory
+ File cfDirectory = parentDirectory;
+ // check if this is secondary index
+ String indexName = "";
+ if (cfDirectory.getName().startsWith(Directories.SECONDARY_INDEX_NAME_SEPARATOR))
+ {
+ indexName = cfDirectory.getName();
+ cfDirectory = cfDirectory.getParentFile();
+ }
+ if (cfDirectory.getName().equals(Directories.BACKUPS_SUBDIR))
+ {
+ cfDirectory = cfDirectory.getParentFile();
+ }
+ else if (cfDirectory.getParentFile().getName().equals(Directories.SNAPSHOT_SUBDIR))
+ {
+ cfDirectory = cfDirectory.getParentFile().getParentFile();
+ }
+ cfname = cfDirectory.getName().split("-")[0] + indexName;
+ ksname = cfDirectory.getParentFile().getName();
+ }
+ else
+ {
+ cfname = tokenStack.pop();
+ ksname = tokenStack.pop();
+ }
+ assert tokenStack.isEmpty() : "Invalid file name " + name + " in " + directory;
- // component suffix
- String component = null;
- if (!skipComponent)
- component = st.nextToken();
- directory = directory != null ? directory : new File(".");
- return Pair.create(new Descriptor(version, directory, ksname, cfname, generation, type), component);
+ return Pair.create(new Descriptor(version, parentDirectory, ksname, cfname, generation, type), component);
}
/**
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/src/java/org/apache/cassandra/io/sstable/SSTable.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/SSTable.java b/src/java/org/apache/cassandra/io/sstable/SSTable.java
index 6eff369..dee024a 100644
--- a/src/java/org/apache/cassandra/io/sstable/SSTable.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTable.java
@@ -150,18 +150,17 @@ public abstract class SSTable
}
/**
- * @return A Descriptor,Component pair. If component is of unknown type, returns CUSTOM component.
+ * @return Descriptor and Component pair. null if given file is not acceptable as SSTable component.
+ * If component is of unknown type, returns CUSTOM component.
*/
- public static Pair<Descriptor,Component> tryComponentFromFilename(File dir, String name)
+ public static Pair<Descriptor, Component> tryComponentFromFilename(File dir, String name)
{
try
{
return Component.fromFilename(dir, name);
}
- catch (NoSuchElementException e)
+ catch (Throwable e)
{
- // A NoSuchElementException is thrown if the name does not match the Descriptor format
- // This is the less impacting change (all calls to this method test for null return)
return null;
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/test/unit/org/apache/cassandra/db/DirectoriesTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/DirectoriesTest.java b/test/unit/org/apache/cassandra/db/DirectoriesTest.java
index 9e6b26b..3e29a89 100644
--- a/test/unit/org/apache/cassandra/db/DirectoriesTest.java
+++ b/test/unit/org/apache/cassandra/db/DirectoriesTest.java
@@ -173,7 +173,7 @@ public class DirectoriesTest
{
if (f.getPath().contains(Directories.SNAPSHOT_SUBDIR) || f.getPath().contains(Directories.BACKUPS_SUBDIR))
assert !listed.contains(f) : f + " should not be listed";
- else if (f.getName().contains("-tmp-"))
+ else if (f.getName().contains("tmp-"))
assert !listed.contains(f) : f + " should not be listed";
else
assert listed.contains(f) : f + " is missing";
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java b/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
index e790005..e784051 100644
--- a/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
+++ b/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
@@ -367,7 +367,7 @@ public class CompactionsTest
SSTableReader sstable = sstables.iterator().next();
int prevGeneration = sstable.descriptor.generation;
- String file = new File(sstable.descriptor.filenameFor(Component.DATA)).getName();
+ String file = new File(sstable.descriptor.filenameFor(Component.DATA)).getAbsolutePath();
// submit user defined compaction on flushed sstable
CompactionManager.instance.forceUserDefinedCompaction(file);
// wait until user defined compaction finishes
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/test/unit/org/apache/cassandra/io/sstable/DescriptorTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/io/sstable/DescriptorTest.java b/test/unit/org/apache/cassandra/io/sstable/DescriptorTest.java
new file mode 100644
index 0000000..71145f7
--- /dev/null
+++ b/test/unit/org/apache/cassandra/io/sstable/DescriptorTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.io.IOException;
+import java.util.UUID;
+
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Test;
+
+import org.apache.cassandra.db.Directories;
+import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.utils.Pair;
+
+import static org.junit.Assert.*;
+
+public class DescriptorTest
+{
+ private final String ksname = "ks";
+ private final String cfname = "cf";
+ private final String cfId = ByteBufferUtil.bytesToHex(ByteBufferUtil.bytes(UUID.randomUUID()));
+ private final File tempDataDir;
+
+ public DescriptorTest() throws IOException
+ {
+ // create CF directories, one without CFID and one with it
+ tempDataDir = File.createTempFile("DescriptorTest", null).getParentFile();
+ }
+
+ @Test
+ public void testFromFilename() throws Exception
+ {
+ File cfIdDir = new File(tempDataDir.getAbsolutePath() + File.separator + ksname + File.separator + cfname + '-' + cfId);
+ testFromFilenameFor(cfIdDir);
+ }
+
+ @Test
+ public void testFromFilenameInBackup() throws Exception
+ {
+ File backupDir = new File(StringUtils.join(new String[]{tempDataDir.getAbsolutePath(), ksname, cfname + '-' + cfId, Directories.BACKUPS_SUBDIR}, File.separator));
+ testFromFilenameFor(backupDir);
+ }
+
+ @Test
+ public void testFromFilenameInSnapshot() throws Exception
+ {
+ File snapshotDir = new File(StringUtils.join(new String[]{tempDataDir.getAbsolutePath(), ksname, cfname + '-' + cfId, Directories.SNAPSHOT_SUBDIR, "snapshot_name"}, File.separator));
+ testFromFilenameFor(snapshotDir);
+ }
+
+ @Test
+ public void testFromFilenameInLegacyDirectory() throws Exception
+ {
+ File cfDir = new File(tempDataDir.getAbsolutePath() + File.separator + ksname + File.separator + cfname);
+ testFromFilenameFor(cfDir);
+ }
+
+ private void testFromFilenameFor(File dir)
+ {
+ // normal
+ checkFromFilename(new Descriptor(dir, ksname, cfname, 1, Descriptor.Type.FINAL), false);
+ // skip component (for streaming lock file)
+ checkFromFilename(new Descriptor(dir, ksname, cfname, 2, Descriptor.Type.FINAL), true);
+ // tmp
+ checkFromFilename(new Descriptor(dir, ksname, cfname, 3, Descriptor.Type.TEMP), false);
+ // secondary index
+ String idxName = "myidx";
+ File idxDir = new File(dir.getAbsolutePath() + File.separator + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName);
+ checkFromFilename(new Descriptor(idxDir, ksname, cfname + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName, 4, Descriptor.Type.FINAL), false);
+ // secondary index tmp
+ checkFromFilename(new Descriptor(idxDir, ksname, cfname + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName, 5, Descriptor.Type.TEMP), false);
+
+ // legacy version
+ checkFromFilename(new Descriptor("ja", dir, ksname, cfname, 1, Descriptor.Type.FINAL), false);
+ // legacy tmp
+ checkFromFilename(new Descriptor("ja", dir, ksname, cfname, 2, Descriptor.Type.TEMP), false);
+ // legacy secondary index
+ checkFromFilename(new Descriptor("ja", dir, ksname, cfname + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName, 3, Descriptor.Type.FINAL), false);
+ }
+
+ private void checkFromFilename(Descriptor original, boolean skipComponent)
+ {
+ File file = new File(skipComponent ? original.baseFilename() : original.filenameFor(Component.DATA));
+
+ Pair<Descriptor, String> pair = Descriptor.fromFilename(file.getParentFile(), file.getName(), skipComponent);
+ Descriptor desc = pair.left;
+
+ assertEquals(original.directory, desc.directory);
+ assertEquals(original.ksname, desc.ksname);
+ assertEquals(original.cfname, desc.cfname);
+ assertEquals(original.version, desc.version);
+ assertEquals(original.generation, desc.generation);
+ assertEquals(original.type, desc.type);
+
+ if (skipComponent)
+ {
+ assertNull(pair.right);
+ }
+ else
+ {
+ assertEquals(Component.DATA.name(), pair.right);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d13a996e/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java b/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java
index 32d07ac..157f89b 100644
--- a/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java
+++ b/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java
@@ -69,10 +69,10 @@ public class SSTableUtils
if(!tempdir.delete() || !tempdir.mkdir())
throw new IOException("Temporary directory creation failed.");
tempdir.deleteOnExit();
- File keyspaceDir = new File(tempdir, keyspaceName);
- keyspaceDir.mkdir();
- keyspaceDir.deleteOnExit();
- File datafile = new File(new Descriptor(keyspaceDir, keyspaceName, cfname, generation, Descriptor.Type.FINAL).filenameFor("Data.db"));
+ File cfDir = new File(tempdir, keyspaceName + File.separator + cfname);
+ cfDir.mkdirs();
+ cfDir.deleteOnExit();
+ File datafile = new File(new Descriptor(cfDir, keyspaceName, cfname, generation, Descriptor.Type.FINAL).filenameFor("Data.db"));
if (!datafile.createNewFile())
throw new IOException("unable to create file " + datafile);
datafile.deleteOnExit();