You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mahout.apache.org by ra...@apache.org on 2018/06/04 14:29:13 UTC

[11/53] [abbrv] [partial] mahout git commit: end of day 6-2-2018

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageAndStdDevTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageAndStdDevTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageAndStdDevTest.java
new file mode 100644
index 0000000..16c8dff
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageAndStdDevTest.java
@@ -0,0 +1,107 @@
+/**
+ * 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.cf.taste.impl.common;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.common.RandomUtils;
+import org.junit.Test;
+
+import java.util.Random;
+
+public final class RunningAverageAndStdDevTest extends TasteTestCase {
+
+  private static final double SMALL_EPSILON = 1.0;
+
+  @Test
+  public void testFull() {
+    RunningAverageAndStdDev average = new FullRunningAverageAndStdDev();
+
+    assertEquals(0, average.getCount());
+    assertTrue(Double.isNaN(average.getAverage()));
+    assertTrue(Double.isNaN(average.getStandardDeviation()));
+
+    average.addDatum(6.0);
+    assertEquals(1, average.getCount());
+    assertEquals(6.0, average.getAverage(), EPSILON);
+    assertTrue(Double.isNaN(average.getStandardDeviation()));
+
+    average.addDatum(6.0);
+    assertEquals(2, average.getCount());
+    assertEquals(6.0, average.getAverage(), EPSILON);
+    assertEquals(0.0, average.getStandardDeviation(), EPSILON);
+
+    average.removeDatum(6.0);
+    assertEquals(1, average.getCount());
+    assertEquals(6.0, average.getAverage(), EPSILON);
+    assertTrue(Double.isNaN(average.getStandardDeviation()));
+
+    average.addDatum(-4.0);
+    assertEquals(2, average.getCount());
+    assertEquals(1.0, average.getAverage(), EPSILON);
+    assertEquals(5.0 * 1.4142135623730951, average.getStandardDeviation(), EPSILON);
+
+    average.removeDatum(4.0);
+    assertEquals(1, average.getCount());
+    assertEquals(-2.0, average.getAverage(), EPSILON);
+    assertTrue(Double.isNaN(average.getStandardDeviation()));
+
+  }
+
+  @Test
+  public void testFullBig() {
+    RunningAverageAndStdDev average = new FullRunningAverageAndStdDev();
+
+    Random r = RandomUtils.getRandom();
+    for (int i = 0; i < 100000; i++) {
+      average.addDatum(r.nextDouble() * 1000.0);
+    }
+    assertEquals(500.0, average.getAverage(), SMALL_EPSILON);
+    assertEquals(1000.0 / Math.sqrt(12.0), average.getStandardDeviation(), SMALL_EPSILON);
+
+  }
+  
+  @Test
+  public void testStddev() {
+    
+    RunningAverageAndStdDev runningAverage = new FullRunningAverageAndStdDev();
+
+    assertEquals(0, runningAverage.getCount());
+    assertTrue(Double.isNaN(runningAverage.getAverage()));
+    runningAverage.addDatum(1.0);
+    assertEquals(1, runningAverage.getCount());
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+    assertTrue(Double.isNaN(runningAverage.getStandardDeviation()));
+    runningAverage.addDatum(1.0);
+    assertEquals(2, runningAverage.getCount());
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+    assertEquals(0.0, runningAverage.getStandardDeviation(), EPSILON);
+
+    runningAverage.addDatum(7.0);
+    assertEquals(3, runningAverage.getCount());
+    assertEquals(3.0, runningAverage.getAverage(), EPSILON); 
+    assertEquals(3.464101552963257, runningAverage.getStandardDeviation(), EPSILON);
+
+    runningAverage.addDatum(5.0);
+    assertEquals(4, runningAverage.getCount());
+    assertEquals(3.5, runningAverage.getAverage(), EPSILON); 
+    assertEquals(3.0, runningAverage.getStandardDeviation(), EPSILON);
+
+  }
+  
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageTest.java
new file mode 100644
index 0000000..6b891c5
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/RunningAverageTest.java
@@ -0,0 +1,75 @@
+/**
+ * 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.cf.taste.impl.common;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.junit.Test;
+
+/** <p>Tests {@link FullRunningAverage}.</p> */
+public final class RunningAverageTest extends TasteTestCase {
+
+  @Test
+  public void testFull() {
+    RunningAverage runningAverage = new FullRunningAverage();
+
+    assertEquals(0, runningAverage.getCount());
+    assertTrue(Double.isNaN(runningAverage.getAverage()));
+    runningAverage.addDatum(1.0);
+    assertEquals(1, runningAverage.getCount());
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.addDatum(1.0);
+    assertEquals(2, runningAverage.getCount());
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.addDatum(4.0);
+    assertEquals(3, runningAverage.getCount());
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.addDatum(-4.0);
+    assertEquals(4, runningAverage.getCount());
+    assertEquals(0.5, runningAverage.getAverage(), EPSILON);
+
+    runningAverage.removeDatum(-4.0);
+    assertEquals(3, runningAverage.getCount());
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.removeDatum(4.0);
+    assertEquals(2, runningAverage.getCount());
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+
+    runningAverage.changeDatum(0.0);
+    assertEquals(2, runningAverage.getCount());
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.changeDatum(2.0);
+    assertEquals(2, runningAverage.getCount());
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+  }
+  
+  @Test
+  public void testCopyConstructor() {
+    RunningAverage runningAverage = new FullRunningAverage();
+
+    runningAverage.addDatum(1.0);
+    runningAverage.addDatum(1.0);
+    assertEquals(2, runningAverage.getCount());
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+
+    RunningAverage copy = new FullRunningAverage(runningAverage.getCount(), runningAverage.getAverage());
+    assertEquals(2, copy.getCount());
+    assertEquals(1.0, copy.getAverage(), EPSILON);
+    
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/SamplingLongPrimitiveIteratorTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/SamplingLongPrimitiveIteratorTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/SamplingLongPrimitiveIteratorTest.java
new file mode 100644
index 0000000..a5b91ff
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/SamplingLongPrimitiveIteratorTest.java
@@ -0,0 +1,91 @@
+/**
+ * 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.cf.taste.impl.common;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.junit.Test;
+
+public final class SamplingLongPrimitiveIteratorTest extends TasteTestCase {
+
+  @Test
+  public void testEmptyCase() {
+    assertFalse(new SamplingLongPrimitiveIterator(
+        countingIterator(0), 0.9999).hasNext());
+    assertFalse(new SamplingLongPrimitiveIterator(
+        countingIterator(0), 1).hasNext());
+  }
+
+  @Test
+  public void testSmallInput() {
+    SamplingLongPrimitiveIterator t = new SamplingLongPrimitiveIterator(
+        countingIterator(1), 0.9999);
+    assertTrue(t.hasNext());
+    assertEquals(0L, t.nextLong());
+    assertFalse(t.hasNext());
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testBadRate1() {
+    new SamplingLongPrimitiveIterator(countingIterator(1), 0.0);
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testBadRate2() {
+    new SamplingLongPrimitiveIterator(countingIterator(1), 1.1);
+  }
+
+  @Test
+  public void testExactSizeMatch() {
+    SamplingLongPrimitiveIterator t = new SamplingLongPrimitiveIterator(
+        countingIterator(10), 1);
+    for (int i = 0; i < 10; i++) {
+      assertTrue(t.hasNext());
+      assertEquals(i, t.next().intValue());
+    }
+    assertFalse(t.hasNext());
+  }
+
+  @Test
+  public void testSample() {
+    double p = 0.1;
+    int n = 1000;
+    double sd = Math.sqrt(n * p * (1.0 - p));
+    for (int i = 0; i < 1000; i++) {
+      SamplingLongPrimitiveIterator t = new SamplingLongPrimitiveIterator(countingIterator(n), p);
+      int k = 0;
+      while (t.hasNext()) {
+        long v = t.nextLong();
+        k++;
+        assertTrue(v >= 0L);
+        assertTrue(v < 1000L);
+      }
+      // Should be +/- 5 standard deviations except in about 1 out of 1.7M cases
+      assertTrue(k >= 100 - 5 * sd);
+      assertTrue(k <= 100 + 5 * sd);
+    }
+  }
+
+  private static LongPrimitiveArrayIterator countingIterator(int to) {
+    long[] data = new long[to];
+    for (int i = 0; i < to; i++) {
+      data[i] = i;
+    }
+    return new LongPrimitiveArrayIterator(data);
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/WeightedRunningAverageTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/WeightedRunningAverageTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/WeightedRunningAverageTest.java
new file mode 100644
index 0000000..daa56e8
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/common/WeightedRunningAverageTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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.cf.taste.impl.common;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.junit.Test;
+
+/**
+ * <p>Tests {@link WeightedRunningAverage} and {@link WeightedRunningAverageAndStdDev}.</p>
+ */
+public final class WeightedRunningAverageTest extends TasteTestCase {
+
+  @Test
+  public void testWeighted() {
+
+    WeightedRunningAverage runningAverage = new WeightedRunningAverage();
+
+    assertEquals(0, runningAverage.getCount());
+    assertTrue(Double.isNaN(runningAverage.getAverage()));
+    runningAverage.addDatum(1.0, 2.0);
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.addDatum(1.0);
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.addDatum(8.0, 0.5);
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.addDatum(-4.0);
+    assertEquals(2.0/3.0, runningAverage.getAverage(), EPSILON);
+
+    runningAverage.removeDatum(-4.0);
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.removeDatum(2.0, 2.0);
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+
+    runningAverage.changeDatum(0.0);
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+    runningAverage.changeDatum(4.0, 0.5);
+    assertEquals(5.0/1.5, runningAverage.getAverage(), EPSILON);
+  }
+
+  @Test
+  public void testWeightedAndStdDev() {
+
+    WeightedRunningAverageAndStdDev runningAverage = new WeightedRunningAverageAndStdDev();
+
+    assertEquals(0, runningAverage.getCount());
+    assertTrue(Double.isNaN(runningAverage.getAverage()));
+    assertTrue(Double.isNaN(runningAverage.getStandardDeviation()));
+
+    runningAverage.addDatum(1.0);
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+    assertTrue(Double.isNaN(runningAverage.getStandardDeviation()));
+    runningAverage.addDatum(1.0, 2.0);
+    assertEquals(1.0, runningAverage.getAverage(), EPSILON);
+    assertEquals(0.0, runningAverage.getStandardDeviation(), EPSILON);
+    runningAverage.addDatum(8.0, 0.5);
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+    assertEquals(Math.sqrt(10.5), runningAverage.getStandardDeviation(), EPSILON);
+    runningAverage.addDatum(-4.0);
+    assertEquals(2.0/3.0, runningAverage.getAverage(), EPSILON);
+    assertEquals(Math.sqrt(15.75), runningAverage.getStandardDeviation(), EPSILON);
+
+    runningAverage.removeDatum(-4.0);
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+    assertEquals(Math.sqrt(10.5), runningAverage.getStandardDeviation(), EPSILON);
+    runningAverage.removeDatum(2.0, 2.0);
+    assertEquals(2.0, runningAverage.getAverage(), EPSILON);
+    assertEquals(Math.sqrt(31.5), runningAverage.getStandardDeviation(), EPSILON);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluatorImplTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluatorImplTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluatorImplTest.java
new file mode 100644
index 0000000..a47327d
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/GenericRecommenderIRStatsEvaluatorImplTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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.cf.taste.impl.eval;
+
+import org.apache.mahout.cf.taste.eval.DataModelBuilder;
+import org.apache.mahout.cf.taste.eval.IRStatistics;
+import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
+import org.apache.mahout.cf.taste.eval.RecommenderIRStatsEvaluator;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
+import org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel;
+import org.apache.mahout.cf.taste.impl.recommender.GenericBooleanPrefItemBasedRecommender;
+import org.apache.mahout.cf.taste.impl.similarity.LogLikelihoodSimilarity;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.recommender.Recommender;
+import org.junit.Test;
+
+public final class GenericRecommenderIRStatsEvaluatorImplTest extends TasteTestCase {
+
+  @Test
+  public void testBoolean() throws Exception {
+    DataModel model = getBooleanDataModel();
+    RecommenderBuilder builder = new RecommenderBuilder() {
+      @Override
+      public Recommender buildRecommender(DataModel dataModel) {
+        return new GenericBooleanPrefItemBasedRecommender(dataModel, new LogLikelihoodSimilarity(dataModel));
+      }
+    };
+    DataModelBuilder dataModelBuilder = new DataModelBuilder() {
+      @Override
+      public DataModel buildDataModel(FastByIDMap<PreferenceArray> trainingData) {
+        return new GenericBooleanPrefDataModel(GenericBooleanPrefDataModel.toDataMap(trainingData));
+      }
+    };
+    RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator();
+    IRStatistics stats = evaluator.evaluate(
+        builder, dataModelBuilder, model, null, 1, GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0);
+
+    assertNotNull(stats);
+    assertEquals(0.666666666, stats.getPrecision(), EPSILON);
+    assertEquals(0.666666666, stats.getRecall(), EPSILON);
+    assertEquals(0.666666666, stats.getF1Measure(), EPSILON);
+    assertEquals(0.666666666, stats.getFNMeasure(2.0), EPSILON);
+    assertEquals(0.666666666, stats.getNormalizedDiscountedCumulativeGain(), EPSILON);
+  }
+
+  @Test
+  public void testIRStats() {
+    IRStatistics stats = new IRStatisticsImpl(0.3, 0.1, 0.2, 0.05, 0.15);
+    assertEquals(0.3, stats.getPrecision(), EPSILON);
+    assertEquals(0.1, stats.getRecall(), EPSILON);
+    assertEquals(0.15, stats.getF1Measure(), EPSILON);
+    assertEquals(0.11538461538462, stats.getFNMeasure(2.0), EPSILON);
+    assertEquals(0.05, stats.getNormalizedDiscountedCumulativeGain(), EPSILON);
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluationRunner.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluationRunner.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluationRunner.java
new file mode 100644
index 0000000..852b3e0
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/eval/LoadEvaluationRunner.java
@@ -0,0 +1,68 @@
+/*
+ * 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.cf.taste.impl.eval;
+
+import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
+import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
+import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
+import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
+import org.apache.mahout.cf.taste.impl.similarity.EuclideanDistanceSimilarity;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
+import org.apache.mahout.cf.taste.recommender.Recommender;
+import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
+import org.apache.mahout.cf.taste.similarity.UserSimilarity;
+
+import java.io.File;
+
+public final class LoadEvaluationRunner {
+
+  private static final int LOOPS = 10;
+
+  private LoadEvaluationRunner() {
+  }
+
+  public static void main(String[] args) throws Exception {
+
+    DataModel model = new FileDataModel(new File(args[0]));
+
+    int howMany = 10;
+    if (args.length > 1) {
+      howMany = Integer.parseInt(args[1]);
+    }
+
+    System.out.println("Run Items");
+    ItemSimilarity similarity = new EuclideanDistanceSimilarity(model);
+    Recommender recommender = new GenericItemBasedRecommender(model, similarity); // Use an item-item recommender
+    for (int i = 0; i < LOOPS; i++) {
+      LoadStatistics loadStats = LoadEvaluator.runLoad(recommender, howMany);
+      System.out.println(loadStats);
+    }
+
+    System.out.println("Run Users");
+    UserSimilarity userSim = new EuclideanDistanceSimilarity(model);
+    UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, userSim, model);
+    recommender = new GenericUserBasedRecommender(model, neighborhood, userSim);
+    for (int i = 0; i < LOOPS; i++) {
+      LoadStatistics loadStats = LoadEvaluator.runLoad(recommender, howMany);
+      System.out.println(loadStats);
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArrayTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArrayTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArrayTest.java
new file mode 100644
index 0000000..384b120
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanItemPreferenceArrayTest.java
@@ -0,0 +1,89 @@
+/**
+ * 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.cf.taste.impl.model;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.junit.Test;
+
+public final class BooleanItemPreferenceArrayTest extends TasteTestCase {
+
+  @Test
+  public void testUserID() {
+    PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setItemID(0, 1L);
+    assertEquals(1L, prefs.getItemID(0));
+    assertEquals(1L, prefs.getItemID(1));
+    assertEquals(1L, prefs.getItemID(2));
+  }
+
+  @Test
+  public void testItemID() {
+    PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setUserID(0, 1L);
+    prefs.setUserID(1, 2L);
+    prefs.setUserID(2, 3L);
+    assertEquals(1L, prefs.getUserID(0));
+    assertEquals(2L, prefs.getUserID(1));
+    assertEquals(3L, prefs.getUserID(2));
+  }
+
+  @Test(expected = UnsupportedOperationException.class)
+  public void testSetValue() {
+    PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    assertEquals(1.0f, prefs.getValue(2), EPSILON);
+    prefs.setValue(0, 1.0f);
+  }
+
+  @Test
+  public void testHasPref() {
+    PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+    prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+    assertTrue(prefs.hasPrefWithItemID(3L));
+    assertTrue(prefs.hasPrefWithUserID(1L));
+    assertFalse(prefs.hasPrefWithItemID(2L));
+    assertFalse(prefs.hasPrefWithUserID(2L));
+  }
+
+  @Test
+  public void testSort() {
+    PreferenceArray prefs = new BooleanItemPreferenceArray(3);
+    prefs.set(0, new GenericPreference(3L, 1L, 5.0f));
+    prefs.set(1, new GenericPreference(1L, 1L, 5.0f));
+    prefs.set(2, new GenericPreference(2L, 1L, 5.0f));
+    prefs.sortByUser();
+    assertEquals(1L, prefs.getUserID(0));
+    assertEquals(2L, prefs.getUserID(1));
+    assertEquals(3L, prefs.getUserID(2));
+  }
+
+  @Test
+  public void testClone() {
+    BooleanItemPreferenceArray prefs = new BooleanItemPreferenceArray(3);
+    prefs.set(0, new BooleanPreference(3L, 1L));
+    prefs.set(1, new BooleanPreference(1L, 1L));
+    prefs.set(2, new BooleanPreference(2L, 1L));
+    prefs = prefs.clone();
+    assertEquals(3L, prefs.getUserID(0));
+    assertEquals(1L, prefs.getItemID(1));
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArrayTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArrayTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArrayTest.java
new file mode 100644
index 0000000..fa1f88c
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/BooleanUserPreferenceArrayTest.java
@@ -0,0 +1,89 @@
+/**
+ * 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.cf.taste.impl.model;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.junit.Test;
+
+public final class BooleanUserPreferenceArrayTest extends TasteTestCase {
+
+  @Test
+  public void testUserID() {
+    PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setUserID(0, 1L);
+    assertEquals(1L, prefs.getUserID(0));
+    assertEquals(1L, prefs.getUserID(1));
+    assertEquals(1L, prefs.getUserID(2));
+  }
+
+  @Test
+  public void testItemID() {
+    PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setItemID(0, 1L);
+    prefs.setItemID(1, 2L);
+    prefs.setItemID(2, 3L);
+    assertEquals(1L, prefs.getItemID(0));
+    assertEquals(2L, prefs.getItemID(1));
+    assertEquals(3L, prefs.getItemID(2));
+  }
+
+  @Test(expected = UnsupportedOperationException.class)
+  public void testSetValue() {
+    PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+    assertEquals(1.0f, prefs.getValue(2), EPSILON);
+    assertEquals(3, prefs.length());
+    prefs.setValue(0, 1.0f);
+  }
+
+  @Test
+  public void testHasPref() {
+    PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+    prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+    assertTrue(prefs.hasPrefWithItemID(3L));
+    assertTrue(prefs.hasPrefWithUserID(1L));
+    assertFalse(prefs.hasPrefWithItemID(2L));
+    assertFalse(prefs.hasPrefWithUserID(2L));
+  }
+
+  @Test
+  public void testSort() {
+    PreferenceArray prefs = new BooleanUserPreferenceArray(3);
+    prefs.set(0, new BooleanPreference(1L, 3L));
+    prefs.set(1, new BooleanPreference(1L, 1L));
+    prefs.set(2, new BooleanPreference(1L, 2L));
+    prefs.sortByItem();
+    assertEquals(1L, prefs.getItemID(0));
+    assertEquals(2L, prefs.getItemID(1));
+    assertEquals(3L, prefs.getItemID(2));
+  }
+
+  @Test  
+  public void testClone() {
+    BooleanUserPreferenceArray prefs = new BooleanUserPreferenceArray(3);
+    prefs.set(0, new BooleanPreference(1L, 3L));
+    prefs.set(1, new BooleanPreference(1L, 1L));
+    prefs.set(2, new BooleanPreference(1L, 2L));
+    prefs = prefs.clone();
+    assertEquals(3L, prefs.getItemID(0));
+    assertEquals(1L, prefs.getUserID(1));
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericDataModelTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericDataModelTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericDataModelTest.java
new file mode 100644
index 0000000..75bf070
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericDataModelTest.java
@@ -0,0 +1,51 @@
+/**
+ * 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.cf.taste.impl.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.junit.Test;
+
+/**
+ * Tests {@link GenericDataModel}.
+ */
+public final class GenericDataModelTest extends TasteTestCase {
+
+  @Test  
+  public void testSerialization() throws Exception {
+    GenericDataModel model = (GenericDataModel) getDataModel();
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    ObjectOutputStream out = new ObjectOutputStream(baos);
+    out.writeObject(model);
+    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+    ObjectInputStream in = new ObjectInputStream(bais);
+    GenericDataModel newModel = (GenericDataModel) in.readObject();
+    assertEquals(model.getNumItems(), newModel.getNumItems());
+    assertEquals(model.getNumUsers(), newModel.getNumUsers());
+    assertEquals(model.getPreferencesFromUser(1L), newModel.getPreferencesFromUser(1L));    
+    assertEquals(model.getPreferencesForItem(1L), newModel.getPreferencesForItem(1L));
+    assertEquals(model.getRawUserData(), newModel.getRawUserData());
+  }
+
+  // Lots of other stuff should be tested but is kind of covered by FileDataModelTest
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericItemPreferenceArrayTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericItemPreferenceArrayTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericItemPreferenceArrayTest.java
new file mode 100644
index 0000000..5d77d0e
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericItemPreferenceArrayTest.java
@@ -0,0 +1,110 @@
+/**
+ * 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.cf.taste.impl.model;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.junit.Test;
+
+public final class GenericItemPreferenceArrayTest extends TasteTestCase {
+
+  @Test
+  public void testUserID() {
+    PreferenceArray prefs = new GenericItemPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setItemID(0, 1L);
+    assertEquals(1L, prefs.getItemID(0));
+    assertEquals(1L, prefs.getItemID(1));
+    assertEquals(1L, prefs.getItemID(2));
+  }
+
+  @Test
+  public void testItemID() {
+    PreferenceArray prefs = new GenericItemPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setUserID(0, 1L);
+    prefs.setUserID(1, 2L);
+    prefs.setUserID(2, 3L);
+    assertEquals(1L, prefs.getUserID(0));
+    assertEquals(2L, prefs.getUserID(1));
+    assertEquals(3L, prefs.getUserID(2));    
+  }
+
+  @Test
+  public void testSetValue() {
+    PreferenceArray prefs = new GenericItemPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setValue(0, 1.0f);
+    prefs.setValue(1, 2.0f);
+    prefs.setValue(2, 3.0f);
+    assertEquals(1.0f, prefs.getValue(0), EPSILON);
+    assertEquals(2.0f, prefs.getValue(1), EPSILON);
+    assertEquals(3.0f, prefs.getValue(2), EPSILON);
+  }
+
+  @Test
+  public void testHasPref() {
+    PreferenceArray prefs = new GenericItemPreferenceArray(3);
+    prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+    assertTrue(prefs.hasPrefWithItemID(3L));
+    assertTrue(prefs.hasPrefWithUserID(1L));
+    assertFalse(prefs.hasPrefWithItemID(2L));
+    assertFalse(prefs.hasPrefWithUserID(2L));
+  }
+
+  @Test
+  public void testSort() {
+    PreferenceArray prefs = new GenericItemPreferenceArray(3);
+    prefs.set(0, new GenericPreference(3L, 1L, 5.0f));
+    prefs.set(1, new GenericPreference(1L, 1L, 5.0f));
+    prefs.set(2, new GenericPreference(2L, 1L, 5.0f));
+    prefs.sortByUser();
+    assertEquals(1L, prefs.getUserID(0));
+    assertEquals(2L, prefs.getUserID(1));
+    assertEquals(3L, prefs.getUserID(2));
+  }
+
+  @Test
+  public void testSortValue() {
+    PreferenceArray prefs = new GenericItemPreferenceArray(3);
+    prefs.set(0, new GenericPreference(3L, 1L, 5.0f));
+    prefs.set(1, new GenericPreference(1L, 1L, 4.0f));
+    prefs.set(2, new GenericPreference(2L, 1L, 3.0f));
+    prefs.sortByValue();
+    assertEquals(2L, prefs.getUserID(0));
+    assertEquals(1L, prefs.getUserID(1));
+    assertEquals(3L, prefs.getUserID(2));
+    prefs.sortByValueReversed();
+    assertEquals(3L, prefs.getUserID(0));
+    assertEquals(1L, prefs.getUserID(1));
+    assertEquals(2L, prefs.getUserID(2));
+  }
+
+  @Test
+  public void testClone() {
+    GenericItemPreferenceArray prefs = new GenericItemPreferenceArray(3);
+    prefs.set(0, new GenericPreference(3L, 1L, 5.0f));
+    prefs.set(1, new GenericPreference(1L, 1L, 4.0f));
+    prefs.set(2, new GenericPreference(2L, 1L, 3.0f));
+    prefs = prefs.clone();
+    assertEquals(3L, prefs.getUserID(0));
+    assertEquals(1L, prefs.getItemID(1));
+    assertEquals(3.0f, prefs.getValue(2), EPSILON);
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArrayTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArrayTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArrayTest.java
new file mode 100644
index 0000000..2bde8cc
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/GenericUserPreferenceArrayTest.java
@@ -0,0 +1,110 @@
+/**
+ * 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.cf.taste.impl.model;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.junit.Test;
+
+public final class GenericUserPreferenceArrayTest extends TasteTestCase {
+
+  @Test
+  public void testUserID() {
+    PreferenceArray prefs = new GenericUserPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setUserID(0, 1L);
+    assertEquals(1L, prefs.getUserID(0));
+    assertEquals(1L, prefs.getUserID(1));
+    assertEquals(1L, prefs.getUserID(2));
+  }
+
+  @Test
+  public void testItemID() {
+    PreferenceArray prefs = new GenericUserPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setItemID(0, 1L);
+    prefs.setItemID(1, 2L);
+    prefs.setItemID(2, 3L);
+    assertEquals(1L, prefs.getItemID(0));
+    assertEquals(2L, prefs.getItemID(1));
+    assertEquals(3L, prefs.getItemID(2));    
+  }
+
+  @Test
+  public void testSetValue() {
+    PreferenceArray prefs = new GenericUserPreferenceArray(3);
+    assertEquals(3, prefs.length());
+    prefs.setValue(0, 1.0f);
+    prefs.setValue(1, 2.0f);
+    prefs.setValue(2, 3.0f);
+    assertEquals(1.0f, prefs.getValue(0), EPSILON);
+    assertEquals(2.0f, prefs.getValue(1), EPSILON);
+    assertEquals(3.0f, prefs.getValue(2), EPSILON);
+  }
+
+  @Test
+  public void testHasPref() {
+    PreferenceArray prefs = new GenericUserPreferenceArray(3);
+    prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+    assertTrue(prefs.hasPrefWithItemID(3L));
+    assertTrue(prefs.hasPrefWithUserID(1L));
+    assertFalse(prefs.hasPrefWithItemID(2L));
+    assertFalse(prefs.hasPrefWithUserID(2L));
+  }
+
+  @Test
+  public void testSort() {
+    PreferenceArray prefs = new GenericUserPreferenceArray(3);
+    prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+    prefs.set(1, new GenericPreference(1L, 1L, 5.0f));
+    prefs.set(2, new GenericPreference(1L, 2L, 5.0f));
+    prefs.sortByItem();
+    assertEquals(1L, prefs.getItemID(0));
+    assertEquals(2L, prefs.getItemID(1));
+    assertEquals(3L, prefs.getItemID(2));    
+  }
+
+  @Test
+  public void testSortValue() {
+    PreferenceArray prefs = new GenericUserPreferenceArray(3);
+    prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+    prefs.set(1, new GenericPreference(1L, 1L, 4.0f));
+    prefs.set(2, new GenericPreference(1L, 2L, 3.0f));
+    prefs.sortByValue();
+    assertEquals(2L, prefs.getItemID(0));
+    assertEquals(1L, prefs.getItemID(1));
+    assertEquals(3L, prefs.getItemID(2));
+    prefs.sortByValueReversed();
+    assertEquals(3L, prefs.getItemID(0));
+    assertEquals(1L, prefs.getItemID(1));
+    assertEquals(2L, prefs.getItemID(2));
+  }
+
+  @Test
+  public void testClone() {
+    GenericUserPreferenceArray prefs = new GenericUserPreferenceArray(3);
+    prefs.set(0, new GenericPreference(1L, 3L, 5.0f));
+    prefs.set(1, new GenericPreference(1L, 1L, 4.0f));
+    prefs.set(2, new GenericPreference(1L, 2L, 3.0f));
+    prefs = prefs.clone();
+    assertEquals(3L, prefs.getItemID(0));
+    assertEquals(1L, prefs.getUserID(1));
+    assertEquals(3.0f, prefs.getValue(2), EPSILON);
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/MemoryIDMigratorTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/MemoryIDMigratorTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/MemoryIDMigratorTest.java
new file mode 100644
index 0000000..c8c673b
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/MemoryIDMigratorTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.cf.taste.impl.model;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.IDMigrator;
+
+import java.util.Collections;
+import org.apache.mahout.cf.taste.model.UpdatableIDMigrator;
+import org.junit.Test;
+
+public final class MemoryIDMigratorTest extends TasteTestCase {
+
+  private static final String DUMMY_STRING = "Mahout";
+  private static final long DUMMY_ID = -6311185995763544451L;
+
+  @Test
+  public void testToLong() {
+    IDMigrator migrator = new MemoryIDMigrator();
+    long id = migrator.toLongID(DUMMY_STRING);
+    assertEquals(DUMMY_ID, id);
+  }
+
+  @Test
+  public void testStore() throws Exception {
+    UpdatableIDMigrator migrator = new MemoryIDMigrator();
+    long id = migrator.toLongID(DUMMY_STRING);
+    assertNull(migrator.toStringID(id));
+    migrator.storeMapping(id, DUMMY_STRING);
+    assertEquals(DUMMY_STRING, migrator.toStringID(id));
+  }
+
+  @Test
+  public void testInitialize() throws Exception {
+    UpdatableIDMigrator migrator = new MemoryIDMigrator();
+    long id = migrator.toLongID(DUMMY_STRING);
+    assertNull(migrator.toStringID(id));
+    migrator.initialize(Collections.singleton(DUMMY_STRING));
+    assertEquals(DUMMY_STRING, migrator.toStringID(id));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/PlusAnonymousConcurrentUserDataModelTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/PlusAnonymousConcurrentUserDataModelTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/PlusAnonymousConcurrentUserDataModelTest.java
new file mode 100644
index 0000000..f33ba33
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/PlusAnonymousConcurrentUserDataModelTest.java
@@ -0,0 +1,313 @@
+/*
+ * 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.cf.taste.impl.model;
+
+import java.util.Iterator;
+import org.apache.mahout.cf.taste.common.NoSuchUserException;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
+import org.apache.mahout.common.MahoutTestCase;
+import org.junit.Test;
+
+public final class PlusAnonymousConcurrentUserDataModelTest extends MahoutTestCase {
+
+	/**
+	 * Prepares a testable object without delegate data
+	 */
+	private static PlusAnonymousConcurrentUserDataModel getTestableWithoutDelegateData(int maxConcurrentUsers) {
+		FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+		return new PlusAnonymousConcurrentUserDataModel(new GenericDataModel(delegatePreferences), maxConcurrentUsers);
+	}
+
+	/**
+	 * Prepares a testable object with delegate data
+	 */
+  private static PlusAnonymousConcurrentUserDataModel getTestableWithDelegateData(
+        int maxConcurrentUsers, FastByIDMap<PreferenceArray> delegatePreferences) {
+		return new PlusAnonymousConcurrentUserDataModel(new GenericDataModel(delegatePreferences), maxConcurrentUsers);
+	}
+
+	/**
+	 * Test taking the first available user
+	 */
+	@Test
+	public void testTakeFirstAvailableUser() {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+		Long expResult = PlusAnonymousUserDataModel.TEMP_USER_ID;
+		Long result = instance.takeAvailableUser();
+		assertEquals(expResult, result);
+	}
+
+	/**
+	 * Test taking the next available user
+	 */
+	@Test
+	public void testTakeNextAvailableUser() {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+    // Skip first user
+    instance.takeAvailableUser();
+		Long result = instance.takeAvailableUser();
+    Long expResult = PlusAnonymousUserDataModel.TEMP_USER_ID + 1;
+    assertEquals(expResult, result);
+	}
+
+	/**
+	 * Test taking an unavailable user
+	 */
+	@Test
+	public void testTakeUnavailableUser() {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(1);
+		// Take the only available user
+		instance.takeAvailableUser();
+		// There are no more users available
+		assertNull(instance.takeAvailableUser());
+	}
+
+	/**
+	 * Test releasing a valid previously taken user
+	 */
+	@Test
+	public void testReleaseValidUser() {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+		Long takenUserID = instance.takeAvailableUser();
+		assertTrue(instance.releaseUser(takenUserID));
+	}
+
+	/**
+	 * Test releasing an invalid user
+	 */
+	@Test
+	public void testReleaseInvalidUser() {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+		assertFalse(instance.releaseUser(Long.MAX_VALUE));
+	}
+
+	/**
+	 * Test releasing a user which had been released earlier
+	 */
+	@Test
+	public void testReleasePreviouslyReleasedUser() {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+		Long takenUserID = instance.takeAvailableUser();
+		assertTrue(instance.releaseUser(takenUserID));
+		assertFalse(instance.releaseUser(takenUserID));
+	}
+
+	/**
+	 * Test setting anonymous user preferences
+	 */
+	@Test
+	public void testSetAndGetTempPreferences() throws TasteException {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+		Long anonymousUserID = instance.takeAvailableUser();
+		PreferenceArray tempPrefs = new GenericUserPreferenceArray(1);
+		tempPrefs.setUserID(0, anonymousUserID);
+		tempPrefs.setItemID(0, 1);
+		instance.setTempPrefs(tempPrefs, anonymousUserID);
+		assertEquals(tempPrefs, instance.getPreferencesFromUser(anonymousUserID));
+		instance.releaseUser(anonymousUserID);
+	}
+
+	/**
+	 * Test setting and getting preferences from several concurrent anonymous users
+	 */
+	@Test
+	public void testSetMultipleTempPreferences() throws TasteException {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+
+		Long anonymousUserID1 = instance.takeAvailableUser();
+		Long anonymousUserID2 = instance.takeAvailableUser();
+
+		PreferenceArray tempPrefs1 = new GenericUserPreferenceArray(1);
+		tempPrefs1.setUserID(0, anonymousUserID1);
+		tempPrefs1.setItemID(0, 1);
+
+		PreferenceArray tempPrefs2 = new GenericUserPreferenceArray(2);
+		tempPrefs2.setUserID(0, anonymousUserID2);
+		tempPrefs2.setItemID(0, 2);
+		tempPrefs2.setUserID(1, anonymousUserID2);
+		tempPrefs2.setItemID(1, 3);
+
+		instance.setTempPrefs(tempPrefs1, anonymousUserID1);
+		instance.setTempPrefs(tempPrefs2, anonymousUserID2);
+
+		assertEquals(tempPrefs1, instance.getPreferencesFromUser(anonymousUserID1));
+		assertEquals(tempPrefs2, instance.getPreferencesFromUser(anonymousUserID2));
+	}
+
+	/**
+	 * Test counting the number of delegate users
+	 */
+	@Test
+	public void testGetNumUsersWithDelegateUsersOnly() throws TasteException {
+    PreferenceArray prefs = new GenericUserPreferenceArray(1);
+    long sampleUserID = 1;
+		prefs.setUserID(0, sampleUserID);
+    long sampleItemID = 11;
+    prefs.setItemID(0, sampleItemID);
+
+		FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+		delegatePreferences.put(sampleUserID, prefs);
+
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithDelegateData(10, delegatePreferences);
+
+		assertEquals(1, instance.getNumUsers());
+	}
+
+	/**
+	 * Test counting the number of anonymous users
+	 */
+	@Test
+	public void testGetNumAnonymousUsers() throws TasteException {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+
+		Long anonymousUserID1 = instance.takeAvailableUser();
+
+		PreferenceArray tempPrefs1 = new GenericUserPreferenceArray(1);
+		tempPrefs1.setUserID(0, anonymousUserID1);
+		tempPrefs1.setItemID(0, 1);
+
+		instance.setTempPrefs(tempPrefs1, anonymousUserID1);
+
+		// Anonymous users should not be included into the universe.
+		assertEquals(0, instance.getNumUsers());
+	}
+
+	/**
+	 * Test retrieve a single preference value of an anonymous user
+	 */
+	@Test
+	public void testGetPreferenceValue() throws TasteException {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+
+		Long anonymousUserID = instance.takeAvailableUser();
+
+		PreferenceArray tempPrefs = new GenericUserPreferenceArray(1);
+    tempPrefs.setUserID(0, anonymousUserID);
+    long sampleItemID = 1;
+    tempPrefs.setItemID(0, sampleItemID);
+    tempPrefs.setValue(0, Float.MAX_VALUE);
+
+		instance.setTempPrefs(tempPrefs, anonymousUserID);
+
+		assertEquals(Float.MAX_VALUE, instance.getPreferenceValue(anonymousUserID, sampleItemID), EPSILON);
+	}
+
+	/**
+	 * Test retrieve preferences for existing non-anonymous user
+	 */
+	@Test
+	public void testGetPreferencesForNonAnonymousUser() throws TasteException {
+    PreferenceArray prefs = new GenericUserPreferenceArray(1);
+    long sampleUserID = 1;
+		prefs.setUserID(0, sampleUserID);
+    long sampleItemID = 11;
+    prefs.setItemID(0, sampleItemID);
+
+		FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+		delegatePreferences.put(sampleUserID, prefs);
+
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithDelegateData(10, delegatePreferences);
+
+		assertEquals(prefs, instance.getPreferencesFromUser(sampleUserID));
+	}
+
+	/**
+	 * Test retrieve preferences for non-anonymous and non-existing user
+	 */
+	@Test(expected=NoSuchUserException.class)
+	public void testGetPreferencesForNonExistingUser() throws TasteException {
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithoutDelegateData(10);
+		// Exception is expected since such user does not exist
+		instance.getPreferencesFromUser(1);
+	}
+
+	/**
+	 * Test retrieving the user IDs and verifying that anonymous ones are not included
+	 */
+	@Test
+	public void testGetUserIDs() throws TasteException {
+    PreferenceArray prefs = new GenericUserPreferenceArray(1);
+    long sampleUserID = 1;
+		prefs.setUserID(0, sampleUserID);
+    long sampleItemID = 11;
+    prefs.setItemID(0, sampleItemID);
+
+		FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+		delegatePreferences.put(sampleUserID, prefs);
+
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithDelegateData(10, delegatePreferences);
+
+		Long anonymousUserID = instance.takeAvailableUser();
+
+		PreferenceArray tempPrefs = new GenericUserPreferenceArray(1);
+		tempPrefs.setUserID(0, anonymousUserID);
+		tempPrefs.setItemID(0, 22);
+
+		instance.setTempPrefs(tempPrefs, anonymousUserID);
+
+		Iterator<Long> userIDs = instance.getUserIDs();
+
+		assertSame(sampleUserID, userIDs.next());
+		assertFalse(userIDs.hasNext());
+	}
+
+	/**
+	 * Test getting preferences for an item.
+	 *
+	 * @throws TasteException
+	 */
+	@Test
+	public void testGetPreferencesForItem() throws TasteException {
+    PreferenceArray prefs = new GenericUserPreferenceArray(2);
+    long sampleUserID = 4;
+		prefs.setUserID(0, sampleUserID);
+    long sampleItemID = 11;
+    prefs.setItemID(0, sampleItemID);
+		prefs.setUserID(1, sampleUserID);
+    long sampleItemID2 = 22;
+    prefs.setItemID(1, sampleItemID2);
+
+		FastByIDMap<PreferenceArray> delegatePreferences = new FastByIDMap<>();
+		delegatePreferences.put(sampleUserID, prefs);
+
+		PlusAnonymousConcurrentUserDataModel instance = getTestableWithDelegateData(10, delegatePreferences);
+
+		Long anonymousUserID = instance.takeAvailableUser();
+
+		PreferenceArray tempPrefs = new GenericUserPreferenceArray(2);
+		tempPrefs.setUserID(0, anonymousUserID);
+		tempPrefs.setItemID(0, sampleItemID);
+		tempPrefs.setUserID(1, anonymousUserID);
+    long sampleItemID3 = 33;
+    tempPrefs.setItemID(1, sampleItemID3);
+
+		instance.setTempPrefs(tempPrefs, anonymousUserID);
+
+		assertEquals(sampleUserID, instance.getPreferencesForItem(sampleItemID).get(0).getUserID());
+		assertEquals(2, instance.getPreferencesForItem(sampleItemID).length());
+		assertEquals(1, instance.getPreferencesForItem(sampleItemID2).length());
+		assertEquals(1, instance.getPreferencesForItem(sampleItemID3).length());
+
+		assertEquals(2, instance.getNumUsersWithPreferenceFor(sampleItemID));
+		assertEquals(1, instance.getNumUsersWithPreferenceFor(sampleItemID, sampleItemID2));
+		assertEquals(1, instance.getNumUsersWithPreferenceFor(sampleItemID, sampleItemID3));
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
new file mode 100644
index 0000000..be59eee
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
@@ -0,0 +1,216 @@
+/**
+ * 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.cf.taste.impl.model.file;
+
+import java.io.File;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.lang3.mutable.MutableBoolean;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
+import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
+import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
+import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
+import org.apache.mahout.cf.taste.recommender.Recommender;
+import org.apache.mahout.cf.taste.similarity.UserSimilarity;
+import org.junit.Before;
+import org.junit.Test;
+
+/** <p>Tests {@link FileDataModel}.</p> */
+public final class FileDataModelTest extends TasteTestCase {
+
+  private static final String[] DATA = {
+      "123,456,0.1",
+      "123,789,0.6",
+      "123,654,0.7",
+      "234,123,0.5",
+      "234,234,1.0",
+      "234,999,0.9",
+      "345,789,0.6",
+      "345,654,0.7",
+      "345,123,1.0",
+      "345,234,0.5",
+      "345,999,0.5",
+      "456,456,0.1",
+      "456,789,0.5",
+      "456,654,0.0",
+      "456,999,0.2",};
+  
+  private static final String[] DATA_SPLITTED_WITH_TWO_SPACES = {
+      "123  456  0.1",
+      "123  789  0.6",
+      "123  654  0.7",
+      "234  123  0.5",
+      "234  234  1.0",
+      "234  999  0.9",
+      "345  789  0.6",
+      "345  654  0.7",
+      "345  123  1.0",
+      "345  234  0.5",
+      "345  999  0.5",
+      "456  456  0.1",
+      "456  789  0.5",
+      "456  654  0.0",
+      "456  999  0.2",};
+
+  private DataModel model;
+  private File testFile;
+
+  @Override
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    testFile = getTestTempFile("test.txt");
+    writeLines(testFile, DATA);
+    model = new FileDataModel(testFile);
+  }
+  
+  @Test
+  public void testReadRegexSplittedFile() throws Exception {
+    File testFile = getTestTempFile("testRegex.txt");
+    writeLines(testFile, DATA_SPLITTED_WITH_TWO_SPACES);
+    FileDataModel model = new FileDataModel(testFile,"\\s+");
+    assertEquals(model.getItemIDsFromUser(123).size(), 3);
+    assertEquals(model.getItemIDsFromUser(456).size(), 4);
+  }
+
+  @Test
+  public void testFile() throws Exception {
+    UserSimilarity userSimilarity = new PearsonCorrelationSimilarity(model);
+    UserNeighborhood neighborhood = new NearestNUserNeighborhood(3, userSimilarity, model);
+    Recommender recommender = new GenericUserBasedRecommender(model, neighborhood, userSimilarity);
+    assertEquals(1, recommender.recommend(123, 3).size());
+    assertEquals(0, recommender.recommend(234, 3).size());
+    assertEquals(1, recommender.recommend(345, 3).size());
+
+    // Make sure this doesn't throw an exception
+    model.refresh(null);
+  }
+
+  @Test
+  public void testTranspose() throws Exception {
+    FileDataModel tModel = new FileDataModel(testFile, true, FileDataModel.DEFAULT_MIN_RELOAD_INTERVAL_MS);
+    PreferenceArray userPrefs = tModel.getPreferencesFromUser(456);
+    assertNotNull("user prefs are null and it shouldn't be", userPrefs);
+    PreferenceArray pref = tModel.getPreferencesForItem(123);
+    assertNotNull("pref is null and it shouldn't be", pref);
+    assertEquals("pref Size: " + pref.length() + " is not: " + 3, 3, pref.length());
+  }
+
+  @Test(expected = NoSuchElementException.class)
+  public void testGetItems() throws Exception {
+    LongPrimitiveIterator it = model.getItemIDs();
+    assertNotNull(it);
+    assertTrue(it.hasNext());
+    assertEquals(123, it.nextLong());
+    assertTrue(it.hasNext());
+    assertEquals(234, it.nextLong());
+    assertTrue(it.hasNext());
+    assertEquals(456, it.nextLong());
+    assertTrue(it.hasNext());
+    assertEquals(654, it.nextLong());
+    assertTrue(it.hasNext());
+    assertEquals(789, it.nextLong());
+    assertTrue(it.hasNext());
+    assertEquals(999, it.nextLong());
+    assertFalse(it.hasNext());
+    it.next();
+  }
+
+  @Test
+  public void testPreferencesForItem() throws Exception {
+    PreferenceArray prefs = model.getPreferencesForItem(456);
+    assertNotNull(prefs);
+    Preference pref1 = prefs.get(0);
+    assertEquals(123, pref1.getUserID());
+    assertEquals(456, pref1.getItemID());
+    Preference pref2 = prefs.get(1);
+    assertEquals(456, pref2.getUserID());
+    assertEquals(456, pref2.getItemID());
+    assertEquals(2, prefs.length());
+  }
+
+  @Test
+  public void testGetNumUsers() throws Exception {
+    assertEquals(4, model.getNumUsers());
+  }
+
+  @Test
+  public void testNumUsersPreferring() throws Exception {
+    assertEquals(2, model.getNumUsersWithPreferenceFor(456));
+    assertEquals(0, model.getNumUsersWithPreferenceFor(111));
+    assertEquals(0, model.getNumUsersWithPreferenceFor(111, 456));
+    assertEquals(2, model.getNumUsersWithPreferenceFor(123, 234));
+  }
+
+  @Test
+  public void testRefresh() throws Exception {
+    final MutableBoolean initialized = new MutableBoolean(false);
+    Runnable initializer = new Runnable() {
+      @Override
+      public void run() {
+        try {
+          model.getNumUsers();
+          initialized.setValue(true);
+        } catch (TasteException te) {
+          // oops
+        }
+      }
+    };
+    new Thread(initializer).start();
+    Thread.sleep(1000L); // wait a second for thread to start and call getNumUsers()
+    model.getNumUsers(); // should block
+    assertTrue(initialized.booleanValue());
+    assertEquals(4, model.getNumUsers());
+  }
+
+  @Test
+  public void testExplicitRefreshAfterCompleteFileUpdate() throws Exception {
+    File file = getTestTempFile("refresh");
+    writeLines(file, "123,456,3.0");
+
+    /* create a FileDataModel that always reloads when the underlying file has changed */
+    FileDataModel dataModel = new FileDataModel(file, false, 0L);
+    assertEquals(3.0f, dataModel.getPreferenceValue(123L, 456L), EPSILON);
+
+    /* change the underlying file,
+     * we have to wait at least a second to see the change in the file's lastModified timestamp */
+    Thread.sleep(2000L);
+    writeLines(file, "123,456,5.0");
+    dataModel.refresh(null);
+
+    assertEquals(5.0f, dataModel.getPreferenceValue(123L, 456L), EPSILON);
+  }
+
+  @Test
+  public void testToString() {
+    assertFalse(model.toString().isEmpty());
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testEmptyFile() throws Exception {
+    File file = getTestTempFile("empty");
+    writeLines(file); //required to create file.
+    new FileDataModel(file);
+  }
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileIDMigratorTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileIDMigratorTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileIDMigratorTest.java
new file mode 100644
index 0000000..0a73315
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileIDMigratorTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.cf.taste.impl.model.file;
+
+import java.io.File;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.IDMigrator;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link FileIDMigrator}
+ */
+public final class FileIDMigratorTest extends TasteTestCase {
+
+  private static final String[] STRING_IDS = {
+      "dog",
+      "cow" };
+
+  private static final String[] UPDATED_STRING_IDS = {
+      "dog",
+      "cow",
+      "donkey" };
+
+  private File testFile;
+
+  @Override
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    testFile = getTestTempFile("test.txt");
+    writeLines(testFile, STRING_IDS);
+  }
+
+  @Test
+  public void testLoadFromFile() throws Exception {
+    IDMigrator migrator = new FileIDMigrator(testFile);
+    long dogAsLong = migrator.toLongID("dog");
+    long cowAsLong = migrator.toLongID("cow");
+    long donkeyAsLong = migrator.toLongID("donkey");
+    assertEquals("dog", migrator.toStringID(dogAsLong));
+    assertEquals("cow", migrator.toStringID(cowAsLong));
+    assertNull(migrator.toStringID(donkeyAsLong));
+  }
+
+  @Test
+  public void testNoRefreshAfterFileUpdate() throws Exception {
+    IDMigrator migrator = new FileIDMigrator(testFile, 0L);
+
+    /* call a method to make sure the original file is loaded */
+    long dogAsLong = migrator.toLongID("dog");
+    migrator.toStringID(dogAsLong);
+
+    /* change the underlying file,
+     * we have to wait at least a second to see the change in the file's lastModified timestamp */
+    Thread.sleep(2000L);
+    writeLines(testFile, UPDATED_STRING_IDS);
+
+    /* we shouldn't see any changes in the data as we have not yet refreshed */
+    long cowAsLong = migrator.toLongID("cow");
+    long donkeyAsLong = migrator.toLongID("donkey");
+    assertEquals("dog", migrator.toStringID(dogAsLong));
+    assertEquals("cow", migrator.toStringID(cowAsLong));
+    assertNull(migrator.toStringID(donkeyAsLong));
+  }
+
+  @Test
+  public void testRefreshAfterFileUpdate() throws Exception {
+    IDMigrator migrator = new FileIDMigrator(testFile, 0L);
+
+    /* call a method to make sure the original file is loaded */
+    long dogAsLong = migrator.toLongID("dog");
+    migrator.toStringID(dogAsLong);
+
+    /* change the underlying file,
+     * we have to wait at least a second to see the change in the file's lastModified timestamp */
+    Thread.sleep(2000L);
+    writeLines(testFile, UPDATED_STRING_IDS);
+
+    migrator.refresh(null);
+
+    long cowAsLong = migrator.toLongID("cow");
+    long donkeyAsLong = migrator.toLongID("donkey");
+    assertEquals("dog", migrator.toStringID(dogAsLong));
+    assertEquals("cow", migrator.toStringID(cowAsLong));
+    assertEquals("donkey", migrator.toStringID(donkeyAsLong));
+  }
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java
new file mode 100644
index 0000000..b057e5b
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java
@@ -0,0 +1,68 @@
+/**
+ * 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.cf.taste.impl.neighborhood;
+
+import org.apache.mahout.cf.taste.common.Refreshable;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.similarity.AbstractItemSimilarity;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.similarity.PreferenceInferrer;
+import org.apache.mahout.cf.taste.similarity.UserSimilarity;
+
+import java.util.Collection;
+
+final class DummySimilarity extends AbstractItemSimilarity implements UserSimilarity {
+
+  DummySimilarity(DataModel dataModel) {
+    super(dataModel);
+  }
+  
+  @Override
+  public double userSimilarity(long userID1, long userID2) throws TasteException {
+    DataModel dataModel = getDataModel();
+    return 1.0 / (1.0 + Math.abs(dataModel.getPreferencesFromUser(userID1).get(0).getValue()
+                                 - dataModel.getPreferencesFromUser(userID2).get(0).getValue()));
+  }
+  
+  @Override
+  public double itemSimilarity(long itemID1, long itemID2) {
+    // Make up something wacky
+    return 1.0 / (1.0 + Math.abs(itemID1 - itemID2));
+  }
+
+  @Override
+  public double[] itemSimilarities(long itemID1, long[] itemID2s) {
+    int length = itemID2s.length;
+    double[] result = new double[length];
+    for (int i = 0; i < length; i++) {
+      result[i] = itemSimilarity(itemID1, itemID2s[i]);
+    }
+    return result;
+  }
+  
+  @Override
+  public void setPreferenceInferrer(PreferenceInferrer inferrer) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void refresh(Collection<Refreshable> alreadyRefreshed) {
+  // do nothing
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java
new file mode 100644
index 0000000..729dc9a
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java
@@ -0,0 +1,53 @@
+/**
+ * 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.cf.taste.impl.neighborhood;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.junit.Test;
+
+/** <p>Tests {@link NearestNUserNeighborhood}.</p> */
+public final class NearestNNeighborhoodTest extends TasteTestCase {
+
+  @Test
+  public void testNeighborhood() throws Exception {
+    DataModel dataModel = getDataModel();
+
+    long[] neighborhood =
+        new NearestNUserNeighborhood(1, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(1);
+    assertNotNull(neighborhood);
+    assertEquals(1, neighborhood.length);
+    assertTrue(arrayContains(neighborhood, 2));
+
+    long[] neighborhood2 =
+        new NearestNUserNeighborhood(2, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(2);
+    assertNotNull(neighborhood2);
+    assertEquals(2, neighborhood2.length);
+    assertTrue(arrayContains(neighborhood2, 1));
+    assertTrue(arrayContains(neighborhood2, 3));
+
+    long[] neighborhood3 =
+        new NearestNUserNeighborhood(4, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(4);
+    assertNotNull(neighborhood3);
+    assertEquals(3, neighborhood3.length);
+    assertTrue(arrayContains(neighborhood3, 1));
+    assertTrue(arrayContains(neighborhood3, 2));
+    assertTrue(arrayContains(neighborhood3, 3));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java
new file mode 100644
index 0000000..c3005a9
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java
@@ -0,0 +1,51 @@
+/**
+ * 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.cf.taste.impl.neighborhood;
+
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.junit.Test;
+
+/** <p>Tests {@link ThresholdUserNeighborhood}.</p> */
+public final class ThresholdNeighborhoodTest extends TasteTestCase {
+
+  @Test
+  public void testNeighborhood() throws Exception {
+    DataModel dataModel = getDataModel();
+
+    long[] neighborhood =
+        new ThresholdUserNeighborhood(1.0, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(1);
+    assertNotNull(neighborhood);
+    assertEquals(0, neighborhood.length);
+
+    long[] neighborhood2 =
+        new ThresholdUserNeighborhood(0.8, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(1);
+    assertNotNull(neighborhood2);
+    assertEquals(1, neighborhood2.length);
+    assertTrue(arrayContains(neighborhood2, 2));
+
+    long[] neighborhood3 =
+        new ThresholdUserNeighborhood(0.6, new DummySimilarity(dataModel), dataModel).getUserNeighborhood(2);
+    assertNotNull(neighborhood3);
+    assertEquals(3, neighborhood3.length);
+    assertTrue(arrayContains(neighborhood3, 1));
+    assertTrue(arrayContains(neighborhood3, 3));
+    assertTrue(arrayContains(neighborhood3, 4));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java
new file mode 100644
index 0000000..5d9f8cc
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/AllUnknownItemsCandidateItemsStrategyTest.java
@@ -0,0 +1,65 @@
+/**
+ * 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.cf.taste.impl.recommender;
+
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.impl.common.FastIDSet;
+import org.apache.mahout.cf.taste.impl.model.GenericPreference;
+import org.apache.mahout.cf.taste.impl.model.GenericUserPreferenceArray;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.apache.mahout.cf.taste.recommender.CandidateItemsStrategy;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import java.util.Collections;
+
+/**
+ * Tests {@link AllUnknownItemsCandidateItemsStrategyTest}
+ */
+public final class AllUnknownItemsCandidateItemsStrategyTest extends TasteTestCase {
+
+  @Test  
+  public void testStrategy() throws TasteException {
+    FastIDSet allItemIDs = new FastIDSet();
+    allItemIDs.addAll(new long[] { 1L, 2L, 3L });
+
+    FastIDSet preferredItemIDs = new FastIDSet(1);
+    preferredItemIDs.add(2L);
+    
+    DataModel dataModel = EasyMock.createMock(DataModel.class);
+    EasyMock.expect(dataModel.getNumItems()).andReturn(3);
+    EasyMock.expect(dataModel.getItemIDs()).andReturn(allItemIDs.iterator());
+
+    PreferenceArray prefArrayOfUser123 = new GenericUserPreferenceArray(Collections.singletonList(
+        new GenericPreference(123L, 2L, 1.0f)));
+
+    CandidateItemsStrategy strategy = new AllUnknownItemsCandidateItemsStrategy();
+
+    EasyMock.replay(dataModel);
+
+    FastIDSet candidateItems = strategy.getCandidateItems(123L, prefArrayOfUser123, dataModel, false);
+    assertEquals(2, candidateItems.size());
+    assertTrue(candidateItems.contains(1L));
+    assertTrue(candidateItems.contains(3L));
+
+    EasyMock.verify(dataModel);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/mahout/blob/5eda9e1f/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java
----------------------------------------------------------------------
diff --git a/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java
new file mode 100644
index 0000000..3ae35b0
--- /dev/null
+++ b/community/mahout-mr/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java
@@ -0,0 +1,78 @@
+/**
+ * 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.cf.taste.impl.recommender;
+
+import org.apache.commons.lang3.mutable.MutableInt;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
+import org.apache.mahout.cf.taste.recommender.IDRescorer;
+import org.apache.mahout.cf.taste.recommender.Recommender;
+import org.junit.Test;
+
+/** <p>Tests {@link CachingRecommender}.</p> */
+public final class CachingRecommenderTest extends TasteTestCase {
+
+  @Test
+  public void testRecommender() throws Exception {
+    MutableInt recommendCount = new MutableInt();
+    Recommender mockRecommender = new MockRecommender(recommendCount);
+
+    Recommender cachingRecommender = new CachingRecommender(mockRecommender);
+    cachingRecommender.recommend(1, 1);
+    assertEquals(1, recommendCount.intValue());
+    cachingRecommender.recommend(2, 1);
+    assertEquals(2, recommendCount.intValue());
+    cachingRecommender.recommend(1, 1);
+    assertEquals(2, recommendCount.intValue());
+    cachingRecommender.recommend(2, 1);
+    assertEquals(2, recommendCount.intValue());
+    cachingRecommender.refresh(null);
+    cachingRecommender.recommend(1, 1);
+    assertEquals(3, recommendCount.intValue());
+    cachingRecommender.recommend(2, 1);
+    assertEquals(4, recommendCount.intValue());
+    cachingRecommender.recommend(3, 1);
+    assertEquals(5, recommendCount.intValue());
+
+    // Results from this recommend() method can be cached...
+    IDRescorer rescorer = NullRescorer.getItemInstance();
+    cachingRecommender.refresh(null);
+    cachingRecommender.recommend(1, 1, rescorer);
+    assertEquals(6, recommendCount.intValue());
+    cachingRecommender.recommend(2, 1, rescorer);
+    assertEquals(7, recommendCount.intValue());
+    cachingRecommender.recommend(1, 1, rescorer);
+    assertEquals(7, recommendCount.intValue());
+    cachingRecommender.recommend(2, 1, rescorer);
+    assertEquals(7, recommendCount.intValue());
+
+    // until you switch Rescorers
+    cachingRecommender.recommend(1, 1, null);
+    assertEquals(8, recommendCount.intValue());
+    cachingRecommender.recommend(2, 1, null);
+    assertEquals(9, recommendCount.intValue());
+
+    cachingRecommender.refresh(null);
+    cachingRecommender.estimatePreference(1, 1);
+    assertEquals(10, recommendCount.intValue());
+    cachingRecommender.estimatePreference(1, 2);
+    assertEquals(11, recommendCount.intValue());
+    cachingRecommender.estimatePreference(1, 2);
+    assertEquals(11, recommendCount.intValue());
+  }
+
+}