You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2009/05/12 01:48:29 UTC
svn commit: r773726 - in /incubator/cassandra/trunk:
src/java/org/apache/cassandra/io/SSTable.java
test/unit/org/apache/cassandra/io/SSTableTest.java
Author: jbellis
Date: Mon May 11 23:48:28 2009
New Revision: 773726
URL: http://svn.apache.org/viewvc?rev=773726&view=rev
Log:
cannonicalize all accesses to indexMetadataMap.
patch by jbellis; reviewed by Jun Rao for CASSANDRA-153
Modified:
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTable.java
incubator/cassandra/trunk/test/unit/org/apache/cassandra/io/SSTableTest.java
Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTable.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTable.java?rev=773726&r1=773725&r2=773726&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTable.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTable.java Mon May 11 23:48:28 2009
@@ -42,7 +42,6 @@
import org.apache.cassandra.utils.BloomFilter;
import org.apache.cassandra.utils.FileUtils;
import org.apache.cassandra.utils.LogUtil;
-import org.apache.cassandra.dht.IPartitioner;
/**
* This class is built on top of the SequenceFile. It stores
@@ -198,7 +197,7 @@
* We do this so that we don't read the index file into memory multiple
* times.
*/
- static Map<String, List<KeyPositionInfo>> indexMetadataMap_ = new Hashtable<String, List<KeyPositionInfo>>();
+ static IndexMap indexMetadataMap_ = new IndexMap();
/**
* This method deletes both the specified data file
@@ -348,7 +347,7 @@
* ctor to read the data in this file.
*/
public SSTable(String dataFileName, IPartitioner partitioner) throws IOException
- {
+ {
dataFile_ = dataFileName;
partitioner_ = partitioner;
init();
@@ -359,7 +358,7 @@
* version for non DB writes to the SSTable.
*/
public SSTable(String directory, String filename, IPartitioner partitioner) throws IOException
- {
+ {
dataFile_ = directory + System.getProperty("file.separator") + filename + "-Data.db";
partitioner_ = partitioner;
blockIndex_ = new TreeMap<String, BlockMetadata>(partitioner_.getReverseDecoratedKeyComparator());
@@ -660,58 +659,43 @@
public static Coordinate getCoordinates(String decoratedKey, IFileReader dataReader, IPartitioner partitioner) throws IOException
{
List<KeyPositionInfo> indexInfo = indexMetadataMap_.get(dataReader.getFileName());
- int size = (indexInfo == null) ? 0 : indexInfo.size();
- long start = 0L;
+ assert indexInfo != null && indexInfo.size() > 0;
+ long start = 0L;
long end;
- if ( size > 0 )
+ int index = Collections.binarySearch(indexInfo, new KeyPositionInfo(decoratedKey, partitioner));
+ if ( index < 0 )
{
- int index = Collections.binarySearch(indexInfo, new KeyPositionInfo(decoratedKey, partitioner));
- if ( index < 0 )
+ /*
+ * We are here which means that the requested
+ * key is not an index.
+ */
+ index = (++index)*(-1);
+ /*
+ * This means key is not present at all. Hence
+ * a scan is in order.
+ */
+ start = (index == 0) ? 0 : indexInfo.get(index - 1).position();
+ if ( index < indexInfo.size())
{
- /*
- * We are here which means that the requested
- * key is not an index.
- */
- index = (++index)*(-1);
- /*
- * This means key is not present at all. Hence
- * a scan is in order.
- */
- start = (index == 0) ? 0 : indexInfo.get(index - 1).position();
- if ( index < size )
- {
- end = indexInfo.get(index).position();
- }
- else
- {
- /* This is the Block Index in the file. */
- end = start;
- }
+ end = indexInfo.get(index).position();
}
else
{
- /*
- * If we are here that means the key is in the index file
- * and we can retrieve it w/o a scan. In reality we would
- * like to have a retreive(key, fromPosition) but for now
- * we use scan(start, start + 1) - a hack.
- */
- start = indexInfo.get(index).position();
+ /* This is the Block Index in the file. */
end = start;
}
}
else
{
/*
- * We are here which means there are less than
- * 128 keys in the system and hence our only recourse
- * is a linear scan from start to finish. Automatically
- * use memory mapping since we have a huge file and very
- * few keys.
+ * If we are here that means the key is in the index file
+ * and we can retrieve it w/o a scan. In reality we would
+ * like to have a retreive(key, fromPosition) but for now
+ * we use scan(start, start + 1) - a hack.
*/
- end = dataReader.getEOF();
- }
-
+ start = indexInfo.get(index).position();
+ end = start;
+ }
return new Coordinate(start, end);
}
@@ -798,9 +782,9 @@
String tmpDataFile = dataFile_;
String dataFileName = dataFile_.replace("-" + temporaryFile_,"");
File dataFile = new File(dataFile_);
- dataFile.renameTo(new File(dataFileName));
- dataFile_ = dataFileName;
- /* Now repair the in memory index associated with the old name */
+ dataFile.renameTo(new File(dataFileName));
+ dataFile_ = dataFileName;
+ /* Now repair the in memory index associated with the old name */
List<KeyPositionInfo> keyPositionInfos = SSTable.indexMetadataMap_.remove(tmpDataFile);
SSTable.indexMetadataMap_.put(dataFile_, keyPositionInfos);
}
@@ -829,5 +813,51 @@
dataWriter_.writeDirect(BasicUtilities.longToByteArray(bloomFilterRelativePosition));
dataWriter_.close();
}
- }
+ }
+
+ /**
+ * wraps a Map to ensure that all filenames used as keys are cannonicalized.
+ * (Note that cannonical paths are cached by the JDK so the performance hit is negligible.)
+ */
+ static class IndexMap
+ {
+ private final Hashtable<String, List<KeyPositionInfo>> hashtable = new Hashtable<String, List<KeyPositionInfo>>();
+
+ private String cannonicalize(String filename)
+ {
+ try
+ {
+ return new File(filename).getCanonicalPath();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public List<KeyPositionInfo> get(String filename)
+ {
+ return hashtable.get(cannonicalize(filename));
+ }
+
+ public List<KeyPositionInfo> put(String filename, List<KeyPositionInfo> value)
+ {
+ return hashtable.put(cannonicalize(filename), value);
+ }
+
+ public void clear()
+ {
+ hashtable.clear();
+ }
+
+ public Set<String> keySet()
+ {
+ return hashtable.keySet();
+ }
+
+ public List<KeyPositionInfo> remove(String filename)
+ {
+ return hashtable.remove(cannonicalize(filename));
+ }
+ }
}
Modified: incubator/cassandra/trunk/test/unit/org/apache/cassandra/io/SSTableTest.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/test/unit/org/apache/cassandra/io/SSTableTest.java?rev=773726&r1=773725&r2=773726&view=diff
==============================================================================
--- incubator/cassandra/trunk/test/unit/org/apache/cassandra/io/SSTableTest.java (original)
+++ incubator/cassandra/trunk/test/unit/org/apache/cassandra/io/SSTableTest.java Mon May 11 23:48:28 2009
@@ -29,7 +29,7 @@
ssTable.close(bf);
// verify
- SSTable.indexMetadataMap_.clear();
+ SSTable.indexMetadataMap_.clear(); // force reloading the index
ssTable = new SSTable(f.getPath() + "-Data.db", new OrderPreservingPartitioner());
FileStruct fs = new FileStruct(SequenceFile.bufferedReader(ssTable.dataFile_, 128 * 1024), new OrderPreservingPartitioner());
fs.seekTo(key);
@@ -60,7 +60,7 @@
ssTable.close(bf);
// verify
- SSTable.indexMetadataMap_.clear();
+ SSTable.indexMetadataMap_.clear(); // force reloading the index
List<String> keys = new ArrayList(map.keySet());
Collections.shuffle(keys);
ssTable = new SSTable(f.getPath() + "-Data.db", new OrderPreservingPartitioner());