Author: tdunning
Date: Wed Sep  8 18:02:13 2010
New Revision: 995169

URL: http://svn.apache.org/viewvc?rev=995169&view=rev
Log:
Cloned parts of uncommons math to provide a fast seed
generation strategy for production programs.

Added:
    
mahout/trunk/math/src/main/java/org/apache/mahout/common/DevURandomSeedGenerator.java
    
mahout/trunk/math/src/main/java/org/apache/mahout/common/FastRandomSeedGenerator.java
Modified:
    mahout/trunk/math/src/main/java/org/apache/mahout/common/RandomWrapper.java

Added: 
mahout/trunk/math/src/main/java/org/apache/mahout/common/DevURandomSeedGenerator.java
URL: 
http://svn.apache.org/viewvc/mahout/trunk/math/src/main/java/org/apache/mahout/common/DevURandomSeedGenerator.java?rev=995169&view=auto
==============================================================================
--- 
mahout/trunk/math/src/main/java/org/apache/mahout/common/DevURandomSeedGenerator.java
 (added)
+++ 
mahout/trunk/math/src/main/java/org/apache/mahout/common/DevURandomSeedGenerator.java
 Wed Sep  8 18:02:13 2010
@@ -0,0 +1,106 @@
+
+
+
+/*
+ * 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.
+ */
+
+/*
+ * ============================================================================
+ * Derived from DevRandomSeedGenerator which has this copyright notice
+ *
+ *    Copyright 2006-2009 Daniel W. Dyer
+ *
+ *    Licensed 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.mahout.common;
+
+import org.uncommons.maths.random.SeedException;
+import org.uncommons.maths.random.SeedGenerator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * RNG seed strategy that gets data from {...@literal /dev/urandom} on systems 
that provide it (e.g.
+ * Solaris/Linux).  If {...@literal /dev/random} does not exist or is not 
accessible, a {...@link
+ * SeedException} is thrown.  The point of pulling from /dev/urandom instead 
of from /dev/random
+ * is that /dev/random will block if it doesn't think it has enough entropy.  
In most production
+ * applications of Mahout, that really isn't necessary.
+ */
+public class DevURandomSeedGenerator implements SeedGenerator {
+  private static final File DEV_URANDOM = new File("/dev/urandom");
+
+  /**
+   * {...@inheritdoc}
+   *
+   * @return The requested number of random bytes, read directly from 
{...@literal /dev/urandom}.
+   * @throws SeedException If {...@literal /dev/urandom} does not exist or is 
not accessible
+   */
+  public byte[] generateSeed(int length) throws SeedException {
+    FileInputStream file = null;
+    try {
+      file = new FileInputStream(DEV_URANDOM);
+      byte[] randomSeed = new byte[length];
+      int count = 0;
+      while (count < length) {
+        int bytesRead = file.read(randomSeed, count, length - count);
+        if (bytesRead == -1) {
+          throw new SeedException("EOF encountered reading random data.");
+        }
+        count += bytesRead;
+      }
+      return randomSeed;
+    }
+    catch (IOException ex) {
+      throw new SeedException("Failed reading from " + DEV_URANDOM.getName(), 
ex);
+    }
+    catch (SecurityException ex) {
+      // Might be thrown if resource access is restricted (such as in
+      // an applet sandbox).
+      throw new SeedException("SecurityManager prevented access to " + 
DEV_URANDOM.getName(), ex);
+    }
+    finally {
+      if (file != null) {
+        try {
+          file.close();
+        }
+        catch (IOException ex) {
+          // Ignore.
+        }
+      }
+    }
+  }
+
+
+  @Override
+  public String toString() {
+    return "/dev/random";
+  }
+}

Added: 
mahout/trunk/math/src/main/java/org/apache/mahout/common/FastRandomSeedGenerator.java
URL: 
http://svn.apache.org/viewvc/mahout/trunk/math/src/main/java/org/apache/mahout/common/FastRandomSeedGenerator.java?rev=995169&view=auto
==============================================================================
--- 
mahout/trunk/math/src/main/java/org/apache/mahout/common/FastRandomSeedGenerator.java
 (added)
+++ 
mahout/trunk/math/src/main/java/org/apache/mahout/common/FastRandomSeedGenerator.java
 Wed Sep  8 18:02:13 2010
@@ -0,0 +1,60 @@
+/*
+ * 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.mahout.common;
+
+import org.uncommons.maths.random.SecureRandomSeedGenerator;
+import org.uncommons.maths.random.SeedException;
+import org.uncommons.maths.random.SeedGenerator;
+
+/**
+ * Implements an uncommons math compatible generator that avoids /dev/random's 
tendency to block
+ * due to entropy underflow.
+ */
+public class FastRandomSeedGenerator implements SeedGenerator {
+  SeedGenerator[] generators = {new DevURandomSeedGenerator(), new 
SecureRandomSeedGenerator()};
+
+  /**
+   * Generate a seed value for a random number generator.  Try the 
/dev/urandom generator
+   * first, and then fall back to SecureRandomSeedGenerator to guarantee a 
result.  On
+   * platforms with /dev/random, /dev/urandom should exist and thus be fast 
and pretty good.
+   * On platforms without /dev/random, the fallback strategies should also be 
pretty fast.
+   *
+   * @param length The length of the seed to generate (in bytes).
+   * @return A byte array containing the seed data.
+   * @throws org.uncommons.maths.random.SeedException
+   *          If a seed cannot be generated for any reason.
+   */
+  public byte[] generateSeed(int length) throws SeedException {
+    SeedException savedException = null;
+    for (SeedGenerator generator : generators) {
+      try {
+        return generator.generateSeed(length);
+      } catch (SeedException e) {
+        if (savedException != null) {
+          savedException.initCause(e);
+        }
+        savedException = e;
+      }
+    }
+    if (savedException != null) {
+      throw savedException;
+    } else {
+      throw new IllegalStateException("Couldn't generate seed, but didn't find 
an exception.  Can't happen.");
+    }
+  }
+}

Modified: 
mahout/trunk/math/src/main/java/org/apache/mahout/common/RandomWrapper.java
URL: 
http://svn.apache.org/viewvc/mahout/trunk/math/src/main/java/org/apache/mahout/common/RandomWrapper.java?rev=995169&r1=995168&r2=995169&view=diff
==============================================================================
--- mahout/trunk/math/src/main/java/org/apache/mahout/common/RandomWrapper.java 
(original)
+++ mahout/trunk/math/src/main/java/org/apache/mahout/common/RandomWrapper.java 
Wed Sep  8 18:02:13 2010
@@ -19,7 +19,6 @@ package org.apache.mahout.common;
 
 import org.uncommons.maths.random.MersenneTwisterRNG;
 import org.uncommons.maths.random.RepeatableRNG;
-import org.uncommons.maths.random.SecureRandomSeedGenerator;
 import org.uncommons.maths.random.SeedException;
 import org.uncommons.maths.random.SeedGenerator;
 
@@ -29,7 +28,7 @@ import java.util.Random;
 public final class RandomWrapper extends Random {
 
   private static final byte[] STANDARD_SEED = 
"Mahout=Hadoop+ML".getBytes(Charset.forName("US-ASCII"));
-  private static final SeedGenerator SEED_GENERATOR = new 
SecureRandomSeedGenerator();
+  private static final SeedGenerator SEED_GENERATOR = new 
FastRandomSeedGenerator();
 
   private static boolean testSeed;
 


Reply via email to