Use canonical path for directory in SSTable descriptor
patch by yukim; reviewed by Paulo Motta for CASSANDRA-10587
diff --git a/CHANGES.txt b/CHANGES.txt
index 78ea961..c8a4f21 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
2.2.6
+ * Use canonical path for directory in SSTable descriptor (CASSANDRA-10587)
* Add cassandra-stress keystore option (CASSANDRA-9325)
* Fix out-of-space error treatment in memtable flushing (CASSANDRA-11448).
* Dont mark sstables as repairing with sub range repairs (CASSANDRA-11451)
diff --git a/src/java/org/apache/cassandra/io/sstable/Descriptor.java b/src/java/org/apache/cassandra/io/sstable/Descriptor.java
index 9f259fe..ed81616 100644
--- a/src/java/org/apache/cassandra/io/sstable/Descriptor.java
+++ b/src/java/org/apache/cassandra/io/sstable/Descriptor.java
@@ -18,6 +18,8 @@
package org.apache.cassandra.io.sstable;
import java.io.File;
+import java.io.IOError;
+import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;
@@ -58,7 +60,7 @@
}
}
-
+ /** canonicalized path to the directory where SSTable resides */
public final File directory;
/** version has the following format: <code>[a-z]+</code> */
public final Version version;
@@ -91,14 +93,21 @@
{
assert version != null && directory != null && ksname != null && cfname != null && formatType.info.getLatestVersion().getClass().equals(version.getClass());
this.version = version;
- this.directory = directory;
+ try
+ {
+ this.directory = directory.getCanonicalFile();
+ }
+ catch (IOException e)
+ {
+ throw new IOError(e);
+ }
this.ksname = ksname;
this.cfname = cfname;
this.generation = generation;
this.type = temp;
this.formatType = formatType;
- hashCode = Objects.hashCode(version, directory, generation, ksname, cfname, temp, formatType);
+ hashCode = Objects.hashCode(version, this.directory, generation, ksname, cfname, temp, formatType);
}
public Descriptor withGeneration(int newGeneration)
@@ -168,8 +177,7 @@
*/
public static Descriptor fromFilename(String filename)
{
- File file = new File(filename);
- return fromFilename(file.getParentFile(), file.getName(), false).left;
+ return fromFilename(filename, false);
}
public static Descriptor fromFilename(String filename, SSTableFormat.Type formatType)
@@ -179,7 +187,7 @@
public static Descriptor fromFilename(String filename, boolean skipComponent)
{
- File file = new File(filename);
+ File file = new File(filename).getAbsoluteFile();
return fromFilename(file.getParentFile(), file.getName(), skipComponent).left;
}
diff --git a/test/unit/org/apache/cassandra/io/sstable/DescriptorTest.java b/test/unit/org/apache/cassandra/io/sstable/DescriptorTest.java
index 70ab8ba..6354fc2 100644
--- a/test/unit/org/apache/cassandra/io/sstable/DescriptorTest.java
+++ b/test/unit/org/apache/cassandra/io/sstable/DescriptorTest.java
@@ -84,16 +84,22 @@
// 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);
+ 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);
+ 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, SSTableFormat.Type.LEGACY), false);
+ checkFromFilename(new Descriptor("ja", dir, ksname, cfname, 1, Descriptor.Type.FINAL,
+ SSTableFormat.Type.LEGACY), false);
// legacy tmp
- checkFromFilename(new Descriptor("ja", dir, ksname, cfname, 2, Descriptor.Type.TEMP, SSTableFormat.Type.LEGACY), false);
+ checkFromFilename(new Descriptor("ja", dir, ksname, cfname, 2, Descriptor.Type.TEMP, SSTableFormat.Type.LEGACY),
+ false);
// legacy secondary index
- checkFromFilename(new Descriptor("ja", dir, ksname, cfname + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName, 3, Descriptor.Type.FINAL, SSTableFormat.Type.LEGACY), false);
+ checkFromFilename(new Descriptor("ja", dir, ksname,
+ cfname + Directories.SECONDARY_INDEX_NAME_SEPARATOR + idxName, 3,
+ Descriptor.Type.FINAL, SSTableFormat.Type.LEGACY), false);
}
private void checkFromFilename(Descriptor original, boolean skipComponent)
@@ -121,23 +127,38 @@
}
@Test
+ public void testEquality()
+ {
+ // Descriptor should be equal when parent directory points to the same directory
+ File dir = new File(".");
+ Descriptor desc1 = new Descriptor(dir, "ks", "cf", 1, Descriptor.Type.FINAL);
+ Descriptor desc2 = new Descriptor(dir.getAbsoluteFile(), "ks", "cf", 1, Descriptor.Type.FINAL);
+ assertEquals(desc1, desc2);
+ assertEquals(desc1.hashCode(), desc2.hashCode());
+ }
+
+ @Test
public void validateNames()
{
- String names[] = {
- /*"system-schema_keyspaces-ka-1-CompressionInfo.db", "system-schema_keyspaces-ka-1-Summary.db",
- "system-schema_keyspaces-ka-1-Data.db", "system-schema_keyspaces-ka-1-TOC.txt",
- "system-schema_keyspaces-ka-1-Digest.sha1", "system-schema_keyspaces-ka-2-CompressionInfo.db",
- "system-schema_keyspaces-ka-1-Filter.db", "system-schema_keyspaces-ka-2-Data.db",
- "system-schema_keyspaces-ka-1-Index.db", "system-schema_keyspaces-ka-2-Digest.sha1",
- "system-schema_keyspaces-ka-1-Statistics.db",
- "system-schema_keyspacest-tmp-ka-1-Data.db",*/
- "system-schema_keyspace-ka-1-"+ SSTableFormat.Type.BIG.name+"-Data.db"
+ String[] names = {
+ // old formats
+ "system-schema_keyspaces-jb-1-Data.db",
+ "system-schema_keyspaces-tmp-jb-1-Data.db",
+ "system-schema_keyspaces-ka-1-big-Data.db",
+ "system-schema_keyspaces-tmp-ka-1-big-Data.db",
+ // 2ndary index
+ "keyspace1-standard1.idx1-ka-1-big-Data.db",
+ // new formats
+ "la-1-big-Data.db",
+ "tmp-la-1-big-Data.db",
+ // 2ndary index
+ ".idx1" + File.separator + "la-1-big-Data.db",
};
for (String name : names)
{
- Descriptor d = Descriptor.fromFilename(name);
+ assertNotNull(Descriptor.fromFilename(name));
}
}