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;