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 2010/11/03 00:32:40 UTC

svn commit: r1030285 - in /cassandra/branches/cassandra-0.7: ./ contrib/py_stress/ interface/thrift/gen-java/org/apache/cassandra/thrift/ src/java/org/apache/cassandra/db/ src/java/org/apache/cassandra/io/util/ src/java/org/apache/cassandra/service/ sr...

Author: jbellis
Date: Tue Nov  2 23:32:39 2010
New Revision: 1030285

URL: http://svn.apache.org/viewvc?rev=1030285&view=rev
Log:
merge from 0.6

Modified:
    cassandra/branches/cassandra-0.7/   (props changed)
    cassandra/branches/cassandra-0.7/CHANGES.txt
    cassandra/branches/cassandra-0.7/contrib/py_stress/stress.py
    cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java   (props changed)
    cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java   (props changed)
    cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java   (props changed)
    cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java   (props changed)
    cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java   (props changed)
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/util/FileUtils.java
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/service/AbstractCassandraDaemon.java
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraDaemon.java
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/CLibrary.java
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/FBUtilities.java

Propchange: cassandra/branches/cassandra-0.7/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Nov  2 23:32:39 2010
@@ -1,4 +1,4 @@
-/cassandra/branches/cassandra-0.6:922689-1030184
+/cassandra/branches/cassandra-0.6:922689-1030284
 /cassandra/trunk:1026516-1026734,1028929
 /incubator/cassandra/branches/cassandra-0.3:774578-796573
 /incubator/cassandra/branches/cassandra-0.4:810145-834239,834349-834350

Modified: cassandra/branches/cassandra-0.7/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/CHANGES.txt?rev=1030285&r1=1030284&r2=1030285&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.7/CHANGES.txt Tue Nov  2 23:32:39 2010
@@ -13,6 +13,7 @@ dev
  * fix jna errno reporting (CASSANDRA-1694)
  * add friendlier error for UnknownHostException on startup (CASSANDRA-1697)
  * include jna dependency in RPM package (CASSANDRA-1690)
+ * add --skip-keys option to stress.py (CASSANDRA-1696)
 
 
 0.7.0-beta3

Modified: cassandra/branches/cassandra-0.7/contrib/py_stress/stress.py
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/contrib/py_stress/stress.py?rev=1030285&r1=1030284&r2=1030285&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/contrib/py_stress/stress.py (original)
+++ cassandra/branches/cassandra-0.7/contrib/py_stress/stress.py Tue Nov  2 23:32:39 2010
@@ -61,6 +61,8 @@ except ImportError:
 parser = OptionParser()
 parser.add_option('-n', '--num-keys', type="int", dest="numkeys",
                   help="Number of keys", default=1000**2)
+parser.add_option('-N', '--skip-keys', type="float", dest="skipkeys",
+                  help="Fraction of keys to skip initially", default=0)
 parser.add_option('-t', '--threads', type="int", dest="threads",
                   help="Number of threads/procs to use", default=50)
 parser.add_option('-c', '--columns', type="int", dest="columns",
@@ -189,7 +191,8 @@ class Operation(Thread):
     def __init__(self, i, opcounts, keycounts, latencies):
         Thread.__init__(self)
         # generator of the keys to be used
-        self.range = xrange(keys_per_thread * i, keys_per_thread * (i + 1))
+        self.range = xrange(int(keys_per_thread * (i + options.skipkeys)), 
+                            keys_per_thread * (i + 1))
         # we can't use a local counter, since that won't be visible to the parent
         # under multiprocessing.  instead, the parent passes a "opcounts" array
         # and an index that is our assigned counter.

Propchange: cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Nov  2 23:32:39 2010
@@ -1,4 +1,4 @@
-/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:922689-1030184
+/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:922689-1030284
 /cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1026516-1026734,1028929
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/Cassandra.java:774578-796573
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/Cassandra.java:810145-834239,834349-834350

Propchange: cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Nov  2 23:32:39 2010
@@ -1,4 +1,4 @@
-/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:922689-1030184
+/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:922689-1030284
 /cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1026516-1026734,1028929
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/column_t.java:774578-792198
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/Column.java:810145-834239,834349-834350

Propchange: cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Nov  2 23:32:39 2010
@@ -1,4 +1,4 @@
-/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:922689-1030184
+/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:922689-1030284
 /cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1026516-1026734,1028929
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/InvalidRequestException.java:774578-796573
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/InvalidRequestException.java:810145-834239,834349-834350

Propchange: cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Nov  2 23:32:39 2010
@@ -1,4 +1,4 @@
-/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:922689-1030184
+/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:922689-1030284
 /cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1026516-1026734,1028929
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/NotFoundException.java:774578-796573
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/NotFoundException.java:810145-834239,834349-834350

Propchange: cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Nov  2 23:32:39 2010
@@ -1,4 +1,4 @@
-/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:922689-1030184
+/cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:922689-1030284
 /cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1026516-1026734,1028929
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/superColumn_t.java:774578-792198
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/SuperColumn.java:810145-834239,834349-834350

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=1030285&r1=1030284&r2=1030285&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Tue Nov  2 23:32:39 2010
@@ -18,46 +18,22 @@
 
 package org.apache.cassandra.db;
 
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
-import java.io.IOError;
-import java.io.IOException;
-import java.io.ObjectInputStream;
+import java.io.*;
 import java.lang.management.ManagementFactory;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.concurrent.ConcurrentSkipListSet;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
+import java.util.*;
+import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Pattern;
-
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 
+import com.google.common.collect.Iterables;
+import org.apache.commons.collections.IteratorUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import org.apache.cassandra.concurrent.JMXEnabledThreadPoolExecutor;
 import org.apache.cassandra.concurrent.NamedThreadFactory;
 import org.apache.cassandra.concurrent.RetryingScheduledThreadPoolExecutor;
@@ -66,47 +42,20 @@ import org.apache.cassandra.config.CFMet
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.db.columniterator.IColumnIterator;
-import org.apache.cassandra.db.columniterator.IdentityQueryFilter;
 import org.apache.cassandra.db.commitlog.CommitLog;
 import org.apache.cassandra.db.commitlog.CommitLogSegment;
-import org.apache.cassandra.db.filter.IFilter;
-import org.apache.cassandra.db.filter.NamesQueryFilter;
-import org.apache.cassandra.db.filter.QueryFilter;
-import org.apache.cassandra.db.filter.QueryPath;
-import org.apache.cassandra.db.filter.SliceQueryFilter;
+import org.apache.cassandra.db.filter.*;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.marshal.BytesType;
 import org.apache.cassandra.db.marshal.LocalByPartionerType;
-import org.apache.cassandra.dht.AbstractBounds;
-import org.apache.cassandra.dht.Bounds;
-import org.apache.cassandra.dht.ByteOrderedPartitioner;
-import org.apache.cassandra.dht.IPartitioner;
-import org.apache.cassandra.dht.LocalPartitioner;
-import org.apache.cassandra.dht.LocalToken;
-import org.apache.cassandra.dht.OrderPreservingPartitioner;
-import org.apache.cassandra.dht.Range;
-import org.apache.cassandra.dht.Token;
-import org.apache.cassandra.io.sstable.Component;
-import org.apache.cassandra.io.sstable.Descriptor;
-import org.apache.cassandra.io.sstable.ReducingKeyIterator;
-import org.apache.cassandra.io.sstable.SSTable;
-import org.apache.cassandra.io.sstable.SSTableReader;
-import org.apache.cassandra.io.sstable.SSTableTracker;
+import org.apache.cassandra.dht.*;
+import org.apache.cassandra.io.sstable.*;
 import org.apache.cassandra.io.util.FileUtils;
 import org.apache.cassandra.service.StorageService;
 import org.apache.cassandra.thrift.IndexClause;
 import org.apache.cassandra.thrift.IndexExpression;
 import org.apache.cassandra.thrift.IndexOperator;
-import org.apache.cassandra.utils.EstimatedHistogram;
-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 org.apache.commons.collections.IteratorUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Iterables;
+import org.apache.cassandra.utils.*;
 
 public class ColumnFamilyStore implements ColumnFamilyStoreMBean
 {
@@ -1536,7 +1485,7 @@ public class ColumnFamilyStore implement
                 {
                     File sourceFile = new File(ssTable.descriptor.filenameFor(component));
                     File targetLink = new File(snapshotDirectoryPath, sourceFile.getName());
-                    FileUtils.createHardLink(sourceFile, targetLink);
+                    CLibrary.createHardLink(sourceFile, targetLink);
                 }
                 if (logger.isDebugEnabled())
                     logger.debug("Snapshot for " + table + " keyspace data file " + ssTable.getFilename() +
@@ -1546,7 +1495,6 @@ public class ColumnFamilyStore implement
             {
                 throw new IOError(e);
             }
-
         }
     }
 

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/util/FileUtils.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/util/FileUtils.java?rev=1030285&r1=1030284&r2=1030285&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/util/FileUtils.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/util/FileUtils.java Tue Nov  2 23:32:39 2010
@@ -182,66 +182,4 @@ public class FileUtils
         // The directory is now empty so now it can be smoked
         deleteWithConfirm(dir);
     }
-
-    /**
-     * Create a hard link for a given file.
-     * 
-     * @param sourceFile      The name of the source file.
-     * @param destinationFile The name of the destination file.
-     * 
-     * @throws IOException if an error has occurred while creating the link.
-     */
-    public static void createHardLink(File sourceFile, File destinationFile) throws IOException
-    {
-        try
-        {
-            int result = CLibrary.link(sourceFile.getAbsolutePath(), destinationFile.getAbsolutePath());
-            assert result == 0; // success is always zero
-        }
-        catch (UnsatisfiedLinkError e)
-        {
-            createHardLinkWithExec(sourceFile, destinationFile);
-        }
-        catch (RuntimeException e)
-        {
-            if (!(e instanceof LastErrorException))
-                throw e;
-            // there are 17 different error codes listed on the man page.  punt until/unless we find which
-            // ones actually turn up in practice.
-            throw new IOException(String.format("Unable to create hard link from %s to %s (errno %d)",
-                                                sourceFile, destinationFile, CLibrary.errno(e)));
-        }
-    }
-
-    private static void createHardLinkWithExec(File sourceFile, File destinationFile) throws IOException
-    {
-        String osname = System.getProperty("os.name");
-        ProcessBuilder pb;
-        if (osname.startsWith("Windows"))
-        {
-            float osversion = Float.parseFloat(System.getProperty("os.version"));
-            if (osversion >= 6.0f)
-            {
-                pb = new ProcessBuilder("cmd", "/c", "mklink", "/H", destinationFile.getAbsolutePath(), sourceFile.getAbsolutePath());
-            }
-            else
-            {
-                pb = new ProcessBuilder("fsutil", "hardlink", "create", destinationFile.getAbsolutePath(), sourceFile.getAbsolutePath());
-            }
-        }
-        else
-        {
-            pb = new ProcessBuilder("ln", sourceFile.getAbsolutePath(), destinationFile.getAbsolutePath());
-            pb.redirectErrorStream(true);
-        }
-        Process p = pb.start();
-        try
-        {
-            p.waitFor();
-        }
-        catch (InterruptedException e)
-        {
-            throw new RuntimeException(e);
-        }
-    }
 }

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/service/AbstractCassandraDaemon.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/service/AbstractCassandraDaemon.java?rev=1030285&r1=1030284&r2=1030285&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/service/AbstractCassandraDaemon.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/service/AbstractCassandraDaemon.java Tue Nov  2 23:32:39 2010
@@ -39,6 +39,7 @@ import org.apache.cassandra.db.SystemTab
 import org.apache.cassandra.db.Table;
 import org.apache.cassandra.db.commitlog.CommitLog;
 import org.apache.cassandra.db.migration.Migration;
+import org.apache.cassandra.utils.CLibrary;
 import org.apache.cassandra.utils.FBUtilities;
 import org.apache.cassandra.utils.Mx4jTool;
 import org.mortbay.thread.ThreadPool;
@@ -70,7 +71,7 @@ public abstract class AbstractCassandraD
     protected void setup() throws IOException
     {
         logger.info("Heap size: {}/{}", Runtime.getRuntime().totalMemory(), Runtime.getRuntime().maxMemory());
-    	FBUtilities.tryMlockall();
+    	CLibrary.tryMlockall();
 
         listenPort = DatabaseDescriptor.getRpcPort();
         listenAddr = DatabaseDescriptor.getRpcAddress();

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraDaemon.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraDaemon.java?rev=1030285&r1=1030284&r2=1030285&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraDaemon.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/thrift/CassandraDaemon.java Tue Nov  2 23:32:39 2010
@@ -52,7 +52,7 @@ public class CassandraDaemon extends org
 
     protected void setup() throws IOException
     {
-        super.setup();                
+        super.setup();
 
         // now we start listening for clients
         final CassandraServer cassandraServer = new CassandraServer();

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/CLibrary.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/CLibrary.java?rev=1030285&r1=1030284&r2=1030285&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/CLibrary.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/CLibrary.java Tue Nov  2 23:32:39 2010
@@ -18,6 +18,9 @@
  */
 package org.apache.cassandra.utils;
 
+import java.io.File;
+import java.io.IOException;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -28,10 +31,10 @@ public final class CLibrary
 {
     private static Logger logger = LoggerFactory.getLogger(CLibrary.class);
 
-    public static final int MCL_CURRENT = 1;
-    public static final int MCL_FUTURE = 2;
+    private static final int MCL_CURRENT = 1;
+    private static final int MCL_FUTURE = 2;
     
-    public static final int ENOMEM = 12;
+    private static final int ENOMEM = 12;
 
     static
     {
@@ -49,12 +52,12 @@ public final class CLibrary
         }
     }
 
-    public static native int mlockall(int flags) throws LastErrorException;
-    public static native int munlockall() throws LastErrorException;
+    private static native int mlockall(int flags) throws LastErrorException;
+    private static native int munlockall() throws LastErrorException;
 
-    public static native int link(String from, String to) throws LastErrorException;
+    private static native int link(String from, String to) throws LastErrorException;
 
-    public static int errno(RuntimeException e)
+    private static int errno(RuntimeException e)
     {
         assert e instanceof LastErrorException;
         try
@@ -69,4 +72,95 @@ public final class CLibrary
     }
 
     private CLibrary() {}
+
+    public static void tryMlockall()
+    {
+        try
+        {
+            int result = mlockall(MCL_CURRENT);
+            assert result == 0; // mlockall should always be zero on success
+        }
+        catch (UnsatisfiedLinkError e)
+        {
+            // this will have already been logged by CLibrary, no need to repeat it
+        }
+        catch (RuntimeException e)
+        {
+            if (!(e instanceof LastErrorException))
+                throw e;
+            if (errno(e) == ENOMEM && System.getProperty("os.name").toLowerCase().contains("linux"))
+            {
+                logger.warn("Unable to lock JVM memory (ENOMEM)."
+                             + " This can result in part of the JVM being swapped out, especially with mmapped I/O enabled."
+                             + " Increase RLIMIT_MEMLOCK or run Cassandra as root.");
+            }
+            else if (!System.getProperty("os.name").toLowerCase().contains("mac"))
+            {
+                // OS X allows mlockall to be called, but always returns an error
+                logger.warn("Unknown mlockall error " + errno(e));
+            }
+        }
+    }
+
+    /**
+     * Create a hard link for a given file.
+     *
+     * @param sourceFile      The name of the source file.
+     * @param destinationFile The name of the destination file.
+     *
+     * @throws java.io.IOException if an error has occurred while creating the link.
+     */
+    public static void createHardLink(File sourceFile, File destinationFile) throws IOException
+    {
+        try
+        {
+            int result = link(sourceFile.getAbsolutePath(), destinationFile.getAbsolutePath());
+            assert result == 0; // success is always zero
+        }
+        catch (UnsatisfiedLinkError e)
+        {
+            createHardLinkWithExec(sourceFile, destinationFile);
+        }
+        catch (RuntimeException e)
+        {
+            if (!(e instanceof LastErrorException))
+                throw e;
+            // there are 17 different error codes listed on the man page.  punt until/unless we find which
+            // ones actually turn up in practice.
+            throw new IOException(String.format("Unable to create hard link from %s to %s (errno %d)",
+                                                sourceFile, destinationFile, errno(e)));
+        }
+    }
+
+    private static void createHardLinkWithExec(File sourceFile, File destinationFile) throws IOException
+    {
+        String osname = System.getProperty("os.name");
+        ProcessBuilder pb;
+        if (osname.startsWith("Windows"))
+        {
+            float osversion = Float.parseFloat(System.getProperty("os.version"));
+            if (osversion >= 6.0f)
+            {
+                pb = new ProcessBuilder("cmd", "/c", "mklink", "/H", destinationFile.getAbsolutePath(), sourceFile.getAbsolutePath());
+            }
+            else
+            {
+                pb = new ProcessBuilder("fsutil", "hardlink", "create", destinationFile.getAbsolutePath(), sourceFile.getAbsolutePath());
+            }
+        }
+        else
+        {
+            pb = new ProcessBuilder("ln", sourceFile.getAbsolutePath(), destinationFile.getAbsolutePath());
+            pb.redirectErrorStream(true);
+        }
+        Process p = pb.start();
+        try
+        {
+            p.waitFor();
+        }
+        catch (InterruptedException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
 }

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/FBUtilities.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/FBUtilities.java?rev=1030285&r1=1030284&r2=1030285&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/FBUtilities.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/utils/FBUtilities.java Tue Nov  2 23:32:39 2010
@@ -638,35 +638,6 @@ public class FBUtilities
         }
     }
 
-    public static void tryMlockall()
-    {
-        try
-        {
-            int result = CLibrary.mlockall(CLibrary.MCL_CURRENT);
-            assert result == 0; // mlockall should always be zero on success
-        }
-        catch (UnsatisfiedLinkError e)
-        {
-            // this will have already been logged by CLibrary, no need to repeat it
-        }
-        catch (RuntimeException e)
-        {
-            if (!(e instanceof LastErrorException))
-                throw e;
-            if (CLibrary.errno(e) == CLibrary.ENOMEM && System.getProperty("os.name").toLowerCase().contains("linux"))
-            {
-                logger_.warn("Unable to lock JVM memory (ENOMEM)."
-                             + " This can result in part of the JVM being swapped out, especially with mmapped I/O enabled."
-                             + " Increase RLIMIT_MEMLOCK or run Cassandra as root.");
-            }
-            else if (!System.getProperty("os.name").toLowerCase().contains("mac"))
-            {
-                // OS X allows mlockall to be called, but always returns an error
-                logger_.warn("Unknown mlockall error " + CLibrary.errno(e));
-            }
-        }
-    }
-
     public static <T extends Comparable> SortedSet<T> singleton(T column)
     {
         return new TreeSet<T>(Arrays.asList(column));