You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mahout.apache.org by sr...@apache.org on 2009/08/04 02:06:50 UTC

svn commit: r800634 [5/7] - in /lucene/mahout/trunk: core/src/main/java/org/apache/mahout/cf/taste/hadoop/ core/src/main/java/org/apache/mahout/cf/taste/impl/common/ core/src/main/java/org/apache/mahout/cf/taste/impl/common/jdbc/ core/src/main/java/org...

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/SpearmanCorrelationSimilarity.java Tue Aug  4 00:06:46 2009
@@ -20,143 +20,102 @@
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.impl.common.RefreshHelper;
-import org.apache.mahout.cf.taste.impl.model.ByItemPreferenceComparator;
-import org.apache.mahout.cf.taste.impl.model.ByValuePreferenceComparator;
-import org.apache.mahout.cf.taste.impl.model.GenericPreference;
 import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
 import org.apache.mahout.cf.taste.similarity.PreferenceInferrer;
 import org.apache.mahout.cf.taste.similarity.UserSimilarity;
 
-import java.util.Arrays;
 import java.util.Collection;
 
 /**
  * <p>Like {@link PearsonCorrelationSimilarity}, but compares relative ranking of preference values instead of
- * preference values themselves. That is, each {@link User}'s preferences are sorted and then assign a rank as their
- * preference value, with 1 being assigned to the least preferred item. Then the Pearson correlation of these rank
- * values is computed.</p>
+ * preference values themselves. That is, each user's preferences are sorted and then assign a rank as their
+ * preference value, with 1 being assigned to the least preferred item.</p>
  */
 public final class SpearmanCorrelationSimilarity implements UserSimilarity {
 
-  private final UserSimilarity rankingUserSimilarity;
+  private final DataModel dataModel;
 
   public SpearmanCorrelationSimilarity(DataModel dataModel) throws TasteException {
     if (dataModel == null) {
       throw new IllegalArgumentException("dataModel is null");
     }
-    this.rankingUserSimilarity = new PearsonCorrelationSimilarity(dataModel);
-  }
-
-  public SpearmanCorrelationSimilarity(UserSimilarity rankingUserSimilarity) {
-    if (rankingUserSimilarity == null) {
-      throw new IllegalArgumentException("rankingUserSimilarity is null");
-    }
-    this.rankingUserSimilarity = rankingUserSimilarity;
-  }
-
-  @Override
-  public double userSimilarity(User user1, User user2) throws TasteException {
-    if (user1 == null || user2 == null) {
-      throw new IllegalArgumentException("user1 or user2 is null");
-    }
-    return rankingUserSimilarity.userSimilarity(new RankedPreferenceUser(user1),
-        new RankedPreferenceUser(user2));
-  }
-
-  @Override
-  public void setPreferenceInferrer(PreferenceInferrer inferrer) {
-    rankingUserSimilarity.setPreferenceInferrer(inferrer);
+    this.dataModel = dataModel;
   }
 
   @Override
-  public void refresh(Collection<Refreshable> alreadyRefreshed) {
-    alreadyRefreshed = RefreshHelper.buildRefreshed(alreadyRefreshed);
-    RefreshHelper.maybeRefresh(alreadyRefreshed, rankingUserSimilarity);
-  }
+  public double userSimilarity(Comparable<?> userID1, Comparable<?> userID2) throws TasteException {
 
-
-  /**
-   * <p>A simple {@link User} decorator which will always return the underlying {@link User}'s preferences in order by
-   * value.</p>
-   */
-  private static final class RankedPreferenceUser implements User {
-
-    private final User delegate;
-
-    private RankedPreferenceUser(User delegate) {
-      this.delegate = delegate;
+    if (userID1 == null || userID2 == null) {
+      throw new IllegalArgumentException("userID1 or userID2 is null");
     }
 
-    @Override
-    public Comparable<?> getID() {
-      return delegate.getID();
-    }
+    PreferenceArray xPrefs = dataModel.getPreferencesFromUser(userID1);
+    PreferenceArray yPrefs = dataModel.getPreferencesFromUser(userID2);
+    int xLength = xPrefs.length();
+    int yLength = yPrefs.length();
 
-    /**
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    public Preference getPreferenceFor(Comparable<?> itemID) {
-      throw new UnsupportedOperationException();
+    if (xLength <= 1 || yLength <= 1) {
+      return Double.NaN;
     }
 
-    /**
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    public void setPreference(Comparable<?> itemID, double value) {
-      throw new UnsupportedOperationException();
-    }
+    xPrefs = xPrefs.clone();
+    yPrefs = yPrefs.clone();
+    
+    xPrefs.sortByValue();
+    yPrefs.sortByValue();
 
-    /**
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    public void removePreference(Comparable<?> itemID) {
-      throw new UnsupportedOperationException();
+    for (int i = 0; i < xLength; i++) {
+      xPrefs.setValue(i, i);
     }
-
-    @Override
-    public Iterable<Preference> getPreferences() {
-      return Arrays.asList(getPreferencesAsArray());
+    for (int i = 0; i < yLength; i++) {
+      yPrefs.setValue(i, i);
     }
 
-    @Override
-    public Preference[] getPreferencesAsArray() {
-      Preference[] source = delegate.getPreferencesAsArray();
-      int length = source.length;
-      Preference[] sortedPrefs = new Preference[length];
-      System.arraycopy(source, 0, sortedPrefs, 0, length);
-      Arrays.sort(sortedPrefs, ByValuePreferenceComparator.getInstance());
-      for (int i = 0; i < length; i++) {
-        sortedPrefs[i] = new GenericPreference(this, sortedPrefs[i].getItemID(), (double) (i + 1));
-      }
-      Arrays.sort(sortedPrefs, ByItemPreferenceComparator.getInstance());
-      return sortedPrefs;
-    }
+    xPrefs.sortByItem();
+    yPrefs.sortByItem();
 
-    @Override
-    public int hashCode() {
-      return delegate.hashCode();
-    }
+    Comparable<?> xIndex = xPrefs.getItemID(0);
+    Comparable<?> yIndex = yPrefs.getItemID(0);
+    int xPrefIndex = 0;
+    int yPrefIndex = 0;
 
-    @Override
-    public boolean equals(Object o) {
-      return o instanceof RankedPreferenceUser && delegate.equals(((RankedPreferenceUser) o).delegate);
-    }
+    double sumXYRankDiff2 = 0.0;
+    int count = 0;
 
-    @Override
-    public int compareTo(User user) {
-      return delegate.compareTo(user);
+    while (true) {
+      int compare = ((Comparable<Object>) xIndex).compareTo(yIndex);
+      if (compare == 0) {
+        double diff = xPrefs.getValue(xPrefIndex) - yPrefs.getValue(yPrefIndex);
+        sumXYRankDiff2 += diff * diff;
+        count++;
+      }
+      if (compare <= 0) {
+        if (++xPrefIndex >= xLength) {
+          break;
+        }
+        xIndex = xPrefs.getItemID(xPrefIndex);
+      }
+      if (compare >= 0) {
+        if (++yPrefIndex >= yLength) {
+          break;
+        }
+        yIndex = yPrefs.getItemID(yPrefIndex);
+      }
     }
 
-    @Override
-    public String toString() {
-      return "RankedPreferenceUser[user:" + delegate + ']';
-    }
+    return 1.0 - (6.0 * sumXYRankDiff2 / count / (count*count - 1));
+  }
 
+  @Override
+  public void setPreferenceInferrer(PreferenceInferrer inferrer) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void refresh(Collection<Refreshable> alreadyRefreshed) {
+    alreadyRefreshed = RefreshHelper.buildRefreshed(alreadyRefreshed);
+    RefreshHelper.maybeRefresh(alreadyRefreshed, dataModel);
   }
 
 }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/TanimotoCoefficientSimilarity.java Tue Aug  4 00:06:46 2009
@@ -19,10 +19,9 @@
 
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastSet;
 import org.apache.mahout.cf.taste.impl.common.RefreshHelper;
 import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
 import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
 import org.apache.mahout.cf.taste.similarity.PreferenceInferrer;
 import org.apache.mahout.cf.taste.similarity.UserSimilarity;
@@ -57,25 +56,25 @@
   }
 
   @Override
-  public double userSimilarity(User user1, User user2) {
+  public double userSimilarity(Comparable<?> userID1, Comparable<?> userID2) throws TasteException {
 
-    if (user1 == null || user2 == null) {
-      throw new IllegalArgumentException("user1 or user2 is null");
+    if (userID1 == null || userID2 == null) {
+      throw new IllegalArgumentException("userID1 or userID2 is null");
     }
 
-    Preference[] xPrefs = user1.getPreferencesAsArray();
-    Preference[] yPrefs = user2.getPreferencesAsArray();
+    FastSet<Comparable<?>> xPrefs = dataModel.getItemIDsFromUser(userID1);
+    FastSet<Comparable<?>> yPrefs = dataModel.getItemIDsFromUser(userID2);
 
-    if (xPrefs.length == 0 && yPrefs.length == 0) {
+    if (xPrefs.isEmpty() && yPrefs.isEmpty()) {
       return Double.NaN;
     }
-    if (xPrefs.length == 0 || yPrefs.length == 0) {
+    if (xPrefs.isEmpty() || yPrefs.isEmpty()) {
       return 0.0;
     }
 
-    int intersectionSize = LogLikelihoodSimilarity.findIntersectionSize(xPrefs, yPrefs);
+    int intersectionSize = xPrefs.intersectionSize(yPrefs);
 
-    int unionSize = xPrefs.length + yPrefs.length - intersectionSize;
+    int unionSize = xPrefs.size() + yPrefs.size() - intersectionSize;
 
     return (double) intersectionSize / (double) unionSize;
   }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/AbstractJDBCItemSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/AbstractJDBCItemSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/AbstractJDBCItemSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/AbstractJDBCItemSimilarity.java Tue Aug  4 00:06:46 2009
@@ -17,22 +17,22 @@
 
 package org.apache.mahout.cf.taste.impl.similarity.jdbc;
 
-import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
-import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.NoSuchItemException;
+import org.apache.mahout.cf.taste.common.Refreshable;
+import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.impl.common.IOUtils;
 import org.apache.mahout.cf.taste.impl.common.jdbc.AbstractJDBCComponent;
 import org.apache.mahout.cf.taste.impl.model.jdbc.ConnectionPoolDataSource;
+import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.sql.DataSource;
-import java.util.Collection;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.Collection;
 
 /**
  * An {@link ItemSimilarity} which draws pre-computed item-item similarities from

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/MySQLJDBCItemSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/MySQLJDBCItemSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/MySQLJDBCItemSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/similarity/jdbc/MySQLJDBCItemSimilarity.java Tue Aug  4 00:06:46 2009
@@ -39,8 +39,8 @@
  *
  * <pre>
  * CREATE TABLE taste_item_similarity (
- *   item_id_a VARCHAR(10) NOT NULL,
- *   item_id_b VARCHAR(10) NOT NULL,
+ *   item_id_a INT NOT NULL,
+ *   item_id_b INT NOT NULL,
  *   similarity FLOAT NOT NULL,
  *   PRIMARY KEY (item_id_a, item_id_b),
  * )

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequency.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequency.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequency.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/InverseUserFrequency.java Tue Aug  4 00:06:46 2009
@@ -20,16 +20,16 @@
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.impl.common.FastMap;
+import org.apache.mahout.cf.taste.impl.common.RefreshHelper;
 import org.apache.mahout.cf.taste.model.DataModel;
 import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
 import org.apache.mahout.cf.taste.transforms.PreferenceTransform;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
+import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
@@ -48,9 +48,8 @@
  */
 public final class InverseUserFrequency implements PreferenceTransform {
 
-  private static final Logger log = LoggerFactory.getLogger(InverseUserFrequency.class);
-
   private final DataModel dataModel;
+  private final RefreshHelper refreshHelper;
   private final double logBase;
   private final AtomicReference<Map<Comparable<?>, Double>> iufFactors;
 
@@ -71,6 +70,14 @@
     this.dataModel = dataModel;
     this.logBase = logBase;
     this.iufFactors = new AtomicReference<Map<Comparable<?>, Double>>(new FastMap<Comparable<?>, Double>());
+    this.refreshHelper = new RefreshHelper(new Callable<Object>() {
+      @Override
+      public Object call() throws TasteException {
+        recompute();
+        return null;
+      }
+    });
+    this.refreshHelper.addDependency(this.dataModel);
     recompute();
   }
 
@@ -80,30 +87,27 @@
   }
 
   @Override
-  public double getTransformedValue(Preference pref) {
+  public float getTransformedValue(Preference pref) {
     Double factor = iufFactors.get().get(pref.getItemID());
     if (factor != null) {
-      return pref.getValue() * factor;
+      return (float) (pref.getValue() * factor);
     }
     return pref.getValue();
   }
 
   @Override
   public void refresh(Collection<Refreshable> alreadyRefreshed) {
-    try {
-      recompute();
-    } catch (TasteException te) {
-      log.warn("Unable to refresh", te);
-    }
+    refreshHelper.refresh(alreadyRefreshed);
   }
 
   private synchronized void recompute() throws TasteException {
     Counters<Comparable<?>> itemPreferenceCounts = new Counters<Comparable<?>>();
     int numUsers = 0;
-    for (User user : dataModel.getUsers()) {
-      Preference[] prefs = user.getPreferencesAsArray();
-      for (Preference pref : prefs) {
-        itemPreferenceCounts.increment(pref.getItemID());
+    for (Comparable<?> userID : dataModel.getUserIDs()) {
+      PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
+      int size = prefs.length();
+      for (int i = 0; i < size; i++) {
+        itemPreferenceCounts.increment(prefs.getItemID(i));
       }
       numUsers++;
     }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/ZScore.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/ZScore.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/ZScore.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/transforms/ZScore.java Tue Aug  4 00:06:46 2009
@@ -21,16 +21,18 @@
 import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.impl.common.Cache;
 import org.apache.mahout.cf.taste.impl.common.FullRunningAverageAndStdDev;
+import org.apache.mahout.cf.taste.impl.common.RefreshHelper;
 import org.apache.mahout.cf.taste.impl.common.Retriever;
 import org.apache.mahout.cf.taste.impl.common.RunningAverageAndStdDev;
+import org.apache.mahout.cf.taste.model.DataModel;
 import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
 import org.apache.mahout.cf.taste.transforms.PreferenceTransform;
 
 import java.util.Collection;
 
 /**
- * <p>Normalizes preference values for a {@link User} by converting them to <a href="http://mathworld.wolfram.com/z-Score.html">"z-scores"</a>.
+ * <p>Normalizes preference values for a user by converting them to <a href="http://mathworld.wolfram.com/z-Score.html">"z-scores"</a>.
  * This process normalizes preference values to adjust for variation in mean and variance of a user's preferences.</p>
  *
  * <p>Imagine two users, one who tends to rate every movie he/she sees four or five stars, and another who uses the full
@@ -39,28 +41,32 @@
  */
 public final class ZScore implements PreferenceTransform {
 
-  private final Cache<User, RunningAverageAndStdDev> meanAndStdevs;
+  private final DataModel dataModel;
+  private final Cache<Comparable<?>, RunningAverageAndStdDev> meanAndStdevs;
 
-  public ZScore() {
-    this.meanAndStdevs = new Cache<User, RunningAverageAndStdDev>(new MeanStdevRetriever());
+  public ZScore(DataModel dataModel) {
+    this.dataModel = dataModel;
+    this.meanAndStdevs = new Cache<Comparable<?>, RunningAverageAndStdDev>(new MeanStdevRetriever());
     refresh(null);
   }
 
   @Override
-  public double getTransformedValue(Preference pref) throws TasteException {
-    RunningAverageAndStdDev meanAndStdev = meanAndStdevs.get(pref.getUser());
+  public float getTransformedValue(Preference pref) throws TasteException {
+    RunningAverageAndStdDev meanAndStdev = meanAndStdevs.get(pref.getUserID());
     if (meanAndStdev.getCount() > 1) {
       double stdev = meanAndStdev.getStandardDeviation();
       if (stdev > 0.0) {
-        return (pref.getValue() - meanAndStdev.getAverage()) / stdev;
+        return (float) ((pref.getValue() - meanAndStdev.getAverage()) / stdev);
       }
     }
-    return 0.0;
+    return 0.0f;
   }
 
   @Override
   public void refresh(Collection<Refreshable> alreadyRefreshed) {
-    // do nothing
+    meanAndStdevs.clear();
+    alreadyRefreshed = RefreshHelper.buildRefreshed(alreadyRefreshed);
+    RefreshHelper.maybeRefresh(alreadyRefreshed, dataModel);
   }
 
   @Override
@@ -68,14 +74,15 @@
     return "ZScore";
   }
 
-  private static class MeanStdevRetriever implements Retriever<User, RunningAverageAndStdDev> {
+  private class MeanStdevRetriever implements Retriever<Comparable<?>, RunningAverageAndStdDev> {
 
     @Override
-    public RunningAverageAndStdDev get(User user) throws TasteException {
+    public RunningAverageAndStdDev get(Comparable<?> userID) throws TasteException {
       RunningAverageAndStdDev running = new FullRunningAverageAndStdDev();
-      Preference[] prefs = user.getPreferencesAsArray();
-      for (Preference pref : prefs) {
-        running.addDatum(pref.getValue());
+      PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
+      int size = prefs.length();
+      for (int i = 0; i < size; i++) {
+        running.addDatum(prefs.getValue(i));
       }
       return running;
     }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/DataModel.java Tue Aug  4 00:06:46 2009
@@ -17,31 +17,41 @@
 
 package org.apache.mahout.cf.taste.model;
 
+import org.apache.mahout.cf.taste.common.NoSuchItemException;
+import org.apache.mahout.cf.taste.common.NoSuchUserException;
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastSet;
 
 import java.util.List;
 
 /**
- * <p>Implementations represent a repository of information about {@link User}s and their associated {@link Preference}s
+ * <p>Implementations represent a repository of information about users and their associated {@link Preference}s
  * for items.</p>
  */
 public interface DataModel extends Refreshable {
 
   /**
-   * @return a {@link List} of all {@link User}s in the model, ordered by {@link User}
+   * @return a {@link List} of all user IDs in the model, in order
    * @throws TasteException if an error occurs while accessing the data
    */
-  Iterable<? extends User> getUsers() throws TasteException;
+  Iterable<Comparable<?>> getUserIDs() throws TasteException;
 
   /**
-   * @param id user ID
-   * @return {@link User} who has that ID
+   * @param userID ID of user to get prefs for
+   * @return user's preferences
+   * @throws NoSuchUserException if the user does not exist
    * @throws TasteException if an error occurs while accessing the data
-   * @throws org.apache.mahout.cf.taste.common.NoSuchUserException
-   *                        if there is no such {@link User}
    */
-  User getUser(Comparable<?> id) throws TasteException;
+  PreferenceArray getPreferencesFromUser(Comparable<?> userID) throws TasteException;
+
+  /**
+   * @param userID ID of user to get prefs for
+   * @return IDs of items user expresses a preference for
+   * @throws NoSuchUserException if the user does not exist
+   * @throws TasteException if an error occurs while accessing the data
+   */
+  FastSet<Comparable<?>> getItemIDsFromUser(Comparable<?> userID) throws TasteException;
 
   /**
    * @return a {@link List} of all item IDs in the model, in order
@@ -51,27 +61,32 @@
 
   /**
    * @param itemID item ID
-   * @return all existing {@link Preference}s expressed for that item, ordered by {@link User}
+   * @return all existing {@link Preference}s expressed for that item, ordered by user ID, as an array
+   * @throws NoSuchItemException if the item does not exist
    * @throws TasteException if an error occurs while accessing the data
    */
-  Iterable<? extends Preference> getPreferencesForItem(Comparable<?> itemID) throws TasteException;
+  PreferenceArray getPreferencesForItem(Comparable<?> itemID) throws TasteException;
 
   /**
-   * @param itemID item ID
-   * @return all existing {@link Preference}s expressed for that item, ordered by {@link User}, as an array
+   * Retrieves the preference value for a single user and item.
+   *
+   * @param userID user ID to get pref value from
+   * @param itemID item ID to get pref value for
+   * @return preference value from the given user for the given item or null if none exists
+   * @throws NoSuchUserException if the user does not exist
    * @throws TasteException if an error occurs while accessing the data
    */
-  Preference[] getPreferencesForItemAsArray(Comparable<?> itemID) throws TasteException;
+  Float getPreferenceValue(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
 
   /**
    * @return total number of items known to the model. This is generally the union of all items
-   *         preferred by at least one {@link User} but could include more.
+   *         preferred by at least one user but could include more.
    * @throws TasteException if an error occurs while accessing the data
    */
   int getNumItems() throws TasteException;
 
   /**
-   * @return total number of {@link User}s known to the model.
+   * @return total number of users known to the model.
    * @throws TasteException if an error occurs while accessing the data
    */
   int getNumUsers() throws TasteException;
@@ -82,6 +97,7 @@
    * @throws TasteException           if an error occurs while accessing the data
    * @throws IllegalArgumentException if itemIDs is null, empty, or larger than 2 elements since currently only queries
    *                                  of up to 2 items are needed and supported
+   * @throws NoSuchItemException if an item does not exist
    */
   int getNumUsersWithPreferenceFor(Comparable<?>... itemIDs) throws TasteException;
 
@@ -91,15 +107,19 @@
    * @param userID user to set preference for
    * @param itemID item to set preference for
    * @param value  preference value
+   * @throws NoSuchItemException if the item does not exist
+   * @throws NoSuchUserException if the user does not exist
    * @throws TasteException if an error occurs while accessing the data
    */
-  void setPreference(Comparable<?> userID, Comparable<?> itemID, double value) throws TasteException;
+  void setPreference(Comparable<?> userID, Comparable<?> itemID, float value) throws TasteException;
 
   /**
    * <p>Removes a particular preference for a user.</p>
    *
    * @param userID user from which to remove preference
    * @param itemID item to remove preference for
+   * @throws NoSuchItemException if the item does not exist
+   * @throws NoSuchUserException if the user does not exist
    * @throws TasteException if an error occurs while accessing the data
    */
   void removePreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/JDBCDataModel.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/JDBCDataModel.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/JDBCDataModel.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/JDBCDataModel.java Tue Aug  4 00:06:46 2009
@@ -17,10 +17,27 @@
 
 package org.apache.mahout.cf.taste.model;
 
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastSet;
+
 import javax.sql.DataSource;
+import java.util.Map;
 
 public interface JDBCDataModel extends DataModel {
 
+  /**
+   * @return {@link DataSource} underlying this model
+   */
   DataSource getDataSource();
 
+  /**
+   * Hmm, should this exist elsewhere? seems like most relevant for a DB
+   * implementation, which is not in memory, which might want to export to memory.
+   *
+   * @return all user preference data
+   */
+  Map<Comparable<?>, PreferenceArray> exportWithPrefs() throws TasteException;
+
+  Map<Comparable<?>, FastSet<Comparable<?>>> exportWithIDsOnly() throws TasteException;
+
 }
\ No newline at end of file

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/Preference.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/Preference.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/Preference.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/Preference.java Tue Aug  4 00:06:46 2009
@@ -19,12 +19,12 @@
 
 /**
  * <p>A {@link Preference} encapsulates an item and a preference value, which indicates the strength of the
- * preference for it. {@link Preference}s are associated to {@link User}s.</p>
+ * preference for it. {@link Preference}s are associated to users.</p>
  */
 public interface Preference {
 
-  /** @return {@link User} who prefers the item */
-  User getUser();
+  /** @return ID of user who prefers the item */
+  Comparable<?> getUserID();
 
   /** @return item ID that is preferred */
   Comparable<?> getItemID();
@@ -33,13 +33,13 @@
    * @return strength of the preference for that item. Zero should indicate "no preference either way"; positive values
    *         indicate preference and negative values indicate dislike
    */
-  double getValue();
+  float getValue();
 
   /**
    * Sets the strength of the preference for this item
    *
    * @param value new preference
    */
-  void setValue(double value);
+  void setValue(float value);
 
 }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/PreferenceArray.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/PreferenceArray.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/PreferenceArray.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/model/PreferenceArray.java Tue Aug  4 00:06:46 2009
@@ -17,26 +17,40 @@
 
 package org.apache.mahout.cf.taste.model;
 
+import java.io.Serializable;
+
 /**
  * An alternate representation of an array of {@link Preference}. Implementations, in theory, can produce a more
  * memory-efficient representation. This is not used yet.
  */
-public interface PreferenceArray {
+public interface PreferenceArray extends Cloneable, Serializable, Iterable<Preference> {
 
+  int length();
+  
   Preference get(int i);
 
   void set(int i, Preference pref);
 
-  User getUser(int i);
+  Comparable<?> getUserID(int i);
 
-  void setUser(int i, User user);
+  void setUserID(int i, Comparable<?> userID);
 
   Comparable<?> getItemID(int i);
 
   void setItemID(int i, Comparable<?> itemID);
 
-  double getValue(int i);
+  float getValue(int i);
+
+  void setValue(int i, float value);
+
+  PreferenceArray clone();
+
+  void sortByUser();
+
+  void sortByItem();
+
+  void sortByValue();
 
-  void setValue(int i, double value);
+  void sortByValueReversed();
 
 }
\ No newline at end of file

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/neighborhood/UserNeighborhood.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/neighborhood/UserNeighborhood.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/neighborhood/UserNeighborhood.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/neighborhood/UserNeighborhood.java Tue Aug  4 00:06:46 2009
@@ -19,22 +19,21 @@
 
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.model.User;
 
 import java.util.Collection;
 
 /**
- * <p>Implementations of this interface compute a "neighborhood" of {@link User}s like a given {@link User}. This
+ * <p>Implementations of this interface compute a "neighborhood" of users like a given user. This
  * neighborhood can be used to compute recommendations then.</p>
  */
 public interface UserNeighborhood extends Refreshable {
 
   /**
    * @param userID ID of user for which a neighborhood will be computed
-   * @return {@link Collection} of {@link User}s in the neighborhood
+   * @return {@link Collection} of IDs of users in the neighborhood
    * @throws org.apache.mahout.cf.taste.common.TasteException
    *          if an error occurs while accessing data
    */
-  Collection<User> getUserNeighborhood(Comparable<?> userID) throws TasteException;
+  Collection<Comparable<?>> getUserNeighborhood(Comparable<?> userID) throws TasteException;
 
 }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ClusteringRecommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ClusteringRecommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ClusteringRecommender.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ClusteringRecommender.java Tue Aug  4 00:06:46 2009
@@ -18,7 +18,6 @@
 package org.apache.mahout.cf.taste.recommender;
 
 import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.model.User;
 
 import java.util.Collection;
 
@@ -26,20 +25,20 @@
 public interface ClusteringRecommender extends Recommender {
 
   /**
-   * <p>Returns the cluster of users to which the given {@link User}, denoted by user ID, belongs.</p>
+   * <p>Returns the cluster of users to which the given user, denoted by user ID, belongs.</p>
    *
    * @param userID user ID for which to find a cluster
-   * @return {@link Collection} of {@link User}s in the requested user's cluster
+   * @return {@link Collection} of IDs of users in the requested user's cluster
    * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
    */
-  Collection<User> getCluster(Comparable<?> userID) throws TasteException;
+  Collection<Comparable<?>> getCluster(Comparable<?> userID) throws TasteException;
 
   /**
    * <p>Returns all clusters of users.</p>
    *
-   * @return {@link Collection} of {@link Collection}s of {@link User}s
+   * @return {@link Collection} of {@link Collection}s of user IDs
    * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
    */
-  Collection<Collection<User>> getClusters() throws TasteException;
+  Collection<Collection<Comparable<?>>> getClusters() throws TasteException;
 
 }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ItemBasedRecommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ItemBasedRecommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ItemBasedRecommender.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/ItemBasedRecommender.java Tue Aug  4 00:06:46 2009
@@ -75,7 +75,7 @@
    * an item and value. The value here does not necessarily have a consistent interpretation or expected range;
    * it will be higher the more influential the item was in the recommendation.</p>
    *
-   * @param userID  ID of {@link org.apache.mahout.cf.taste.model.User} who was recommended the item
+   * @param userID  ID of user who was recommended the item
    * @param itemID  ID of item that was recommended
    * @param howMany maximum number of items to return
    * @return {@link List} of {@link RecommendedItem}, ordered from most influential in recommended the

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/RecommendedItem.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/RecommendedItem.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/RecommendedItem.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/RecommendedItem.java Tue Aug  4 00:06:46 2009
@@ -32,6 +32,6 @@
    *
    * @return strength of the preference
    */
-  double getValue();
+  float getValue();
 
 }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Recommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Recommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Recommender.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Recommender.java Tue Aug  4 00:06:46 2009
@@ -24,7 +24,7 @@
 import java.util.List;
 
 /**
- * <p>Implementations of this interface can recommend items for a {@link org.apache.mahout.cf.taste.model.User}.
+ * <p>Implementations of this interface can recommend items for a user.
  * Implementations will likely take advantage of several classes in other packages here to compute this.</p>
  */
 public interface Recommender extends Refreshable {
@@ -33,7 +33,7 @@
    * @param userID  user for which recommendations are to be computed
    * @param howMany desired number of recommendations
    * @return {@link List} of recommended {@link RecommendedItem}s, ordered from most strongly recommend to least
-   * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+   * @throws TasteException if an error occurs while accessing the {@link DataModel}
    */
   List<RecommendedItem> recommend(Comparable<?> userID, int howMany) throws TasteException;
 
@@ -42,7 +42,7 @@
    * @param howMany  desired number of recommendations
    * @param rescorer rescoring function to apply before final list of recommendations is determined
    * @return {@link List} of recommended {@link RecommendedItem}s, ordered from most strongly recommend to least
-   * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+   * @throws TasteException if an error occurs while accessing the {@link DataModel}
    */
   List<RecommendedItem> recommend(Comparable<?> userID, int howMany, Rescorer<Comparable<?>> rescorer)
           throws TasteException;
@@ -52,22 +52,22 @@
    * @param itemID item ID to estimate preference for
    * @return an estimated preference if the user has not expressed a preference for the item, or else the user's actual
    *         preference for the item. If a preference cannot be estimated, returns {@link Double#NaN}
-   * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+   * @throws TasteException if an error occurs while accessing the {@link DataModel}
    */
-  double estimatePreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
+  float estimatePreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
 
   /**
    * @param userID user to set preference for
    * @param itemID item to set preference for
    * @param value  preference value
-   * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+   * @throws TasteException if an error occurs while accessing the {@link DataModel}
    */
-  void setPreference(Comparable<?> userID, Comparable<?> itemID, double value) throws TasteException;
+  void setPreference(Comparable<?> userID, Comparable<?> itemID, float value) throws TasteException;
 
   /**
    * @param userID user from which to remove preference
    * @param itemID item for which to remove preference
-   * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
+   * @throws TasteException if an error occurs while accessing the {@link DataModel}
    */
   void removePreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
 

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Rescorer.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Rescorer.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Rescorer.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/Rescorer.java Tue Aug  4 00:06:46 2009
@@ -18,8 +18,8 @@
 package org.apache.mahout.cf.taste.recommender;
 
 /**
- * <p>A {@link Rescorer} simply assigns a new "score" to a thing like an {@link org.apache.mahout.cf.taste.model.Item}
- * or {@link org.apache.mahout.cf.taste.model.User} which a {@link Recommender} is considering returning as a top
+ * <p>A {@link Rescorer} simply assigns a new "score" to a thing like an ID of an item
+ * or user which a {@link Recommender} is considering returning as a top
  * recommendation. It may be used to arbitrarily re-rank the results according to application-specific logic before
  * returning recommendations. For example, an application may want to boost the score of items in a certain category
  * just for one request.</p>
@@ -30,8 +30,7 @@
 public interface Rescorer<T> {
 
   /**
-   * @param thing         thing ({@link org.apache.mahout.cf.taste.model.Item} or {@link org.apache.mahout.cf.taste.model.User}
-   *                      really) to rescore
+   * @param thing         thing to rescore
    * @param originalScore original score
    * @return modified score, or {@link Double#NaN} to indicate that this should be excluded entirely
    */

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/UserBasedRecommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/UserBasedRecommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/UserBasedRecommender.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/UserBasedRecommender.java Tue Aug  4 00:06:46 2009
@@ -18,7 +18,6 @@
 
 import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.impl.common.Pair;
-import org.apache.mahout.cf.taste.model.User;
 
 import java.util.List;
 
@@ -26,22 +25,24 @@
 public interface UserBasedRecommender extends Recommender {
 
   /**
-   * @param userID  ID of {@link User} for which to find most similar other {@link User}s
-   * @param howMany desired number of most similar {@link User}s to find
-   * @return {@link User}s most similar to the given user
+   * @param userID  ID of user for which to find most similar other users
+   * @param howMany desired number of most similar users to find
+   * @return users most similar to the given user
    * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
    */
-  List<User> mostSimilarUsers(Comparable<?> userID, int howMany) throws TasteException;
+  List<Comparable<?>> mostSimilarUserIDs(Comparable<?> userID, int howMany) throws TasteException;
 
   /**
-   * @param userID   ID of {@link User} for which to find most similar other {@link User}s
-   * @param howMany  desired number of most similar {@link User}s to find
+   * @param userID   ID of user for which to find most similar other users
+   * @param howMany  desired number of most similar users to find
    * @param rescorer {@link Rescorer} which can adjust user-user similarity estimates used to determine most similar
    *                 users
-   * @return {@link User}s most similar to the given user
+   * @return IDs of users most similar to the given user
    * @throws TasteException if an error occurs while accessing the {@link org.apache.mahout.cf.taste.model.DataModel}
    */
-  List<User> mostSimilarUsers(Comparable<?> userID, int howMany, Rescorer<Pair<User, User>> rescorer)
-          throws TasteException;
+  List<Comparable<?>> mostSimilarUserIDs(Comparable<?> userID,
+                                         int howMany,
+                                         Rescorer<Pair<Comparable<?>,
+                                         Comparable<?>>> rescorer) throws TasteException;
 
 }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/slopeone/DiffStorage.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/slopeone/DiffStorage.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/slopeone/DiffStorage.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/recommender/slopeone/DiffStorage.java Tue Aug  4 00:06:46 2009
@@ -20,7 +20,7 @@
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
 import org.apache.mahout.cf.taste.impl.common.RunningAverage;
-import org.apache.mahout.cf.taste.model.Preference;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
 
 import java.util.List;
 import java.util.Set;
@@ -47,7 +47,7 @@
    * @param prefs  user's preferendces
    * @return {@link List} of {@link RunningAverage} for that user's item-item diffs
    */
-  RunningAverage[] getDiffs(Comparable<?> userID, Comparable<?> itemID, Preference[] prefs) throws TasteException;
+  RunningAverage[] getDiffs(Comparable<?> userID, Comparable<?> itemID, PreferenceArray prefs) throws TasteException;
 
   /** @return {@link RunningAverage} encapsulating the average preference for the given item */
   RunningAverage getAverageItemPref(Comparable<?> itemID) throws TasteException;
@@ -59,7 +59,7 @@
    * @param prefDelta amount by which preference value changed (or its old value, if being removed
    * @param remove    if <code>true</code>, operation reflects a removal rather than change of preference
    */
-  void updateItemPref(Comparable<?> itemID, double prefDelta, boolean remove) throws TasteException;
+  void updateItemPref(Comparable<?> itemID, float prefDelta, boolean remove) throws TasteException;
 
   /**
    * @return item IDs that may possibly be recommended to the given user, which may not be all items since

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/ItemSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/ItemSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/ItemSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/ItemSimilarity.java Tue Aug  4 00:06:46 2009
@@ -29,8 +29,8 @@
 public interface ItemSimilarity extends Refreshable {
 
   /**
-   * <p>Returns the degree of similarity, of two items, based on the preferences that {@link
-   * org.apache.mahout.cf.taste.model.User}s have expressed for the items.</p>
+   * <p>Returns the degree of similarity, of two items, based on the preferences that
+   * users have expressed for the items.</p>
    *
    * @param itemID1 first item ID
    * @param itemID2 second item ID

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/PreferenceInferrer.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/PreferenceInferrer.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/PreferenceInferrer.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/PreferenceInferrer.java Tue Aug  4 00:06:46 2009
@@ -19,23 +19,22 @@
 
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.model.User;
 
 /**
- * <p>Implementations of this interface compute an inferred preference for a {@link User} and an item that the
+ * <p>Implementations of this interface compute an inferred preference for a user and an item that the
  * user has not expressed any preference for. This might be an average of other preferences scores from that user, for
  * example. This technique is sometimes called "default voting".</p>
  */
 public interface PreferenceInferrer extends Refreshable {
 
   /**
-   * <p>Infers the given {@link User}'s preference value for an item.</p>
+   * <p>Infers the given user's preference value for an item.</p>
    *
-   * @param user {@link User} to infer preference for
+   * @param userID ID of user to infer preference for
    * @param itemID item ID to infer preference for
    * @return inferred preference
    * @throws TasteException if an error occurs while inferring
    */
-  double inferPreference(User user, Comparable<?> itemID) throws TasteException;
+  float inferPreference(Comparable<?> userID, Comparable<?> itemID) throws TasteException;
 
 }

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/UserSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/UserSimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/UserSimilarity.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/similarity/UserSimilarity.java Tue Aug  4 00:06:46 2009
@@ -19,10 +19,9 @@
 
 import org.apache.mahout.cf.taste.common.Refreshable;
 import org.apache.mahout.cf.taste.common.TasteException;
-import org.apache.mahout.cf.taste.model.User;
 
 /**
- * <p>Implementations of this interface define a notion of similarity between two {@link User}s. Implementations should
+ * <p>Implementations of this interface define a notion of similarity between two users. Implementations should
  * return values in the range -1.0 to 1.0, with 1.0 representing perfect similarity.</p>
  *
  * @see ItemSimilarity
@@ -30,14 +29,14 @@
 public interface UserSimilarity extends Refreshable {
 
   /**
-   * <p>Returns the degree of similarity, of two {@link User}s, based on the their preferences.</p>
+   * <p>Returns the degree of similarity, of two users, based on the their preferences.</p>
    *
-   * @param user1 first user
-   * @param user2 second user
+   * @param userID1 first user ID
+   * @param userID2 second user ID
    * @return similarity between the two users, in [-1,1]
    * @throws TasteException if an error occurs while accessing the data
    */
-  double userSimilarity(User user1, User user2) throws TasteException;
+  double userSimilarity(Comparable<?> userID1, Comparable<?> userID2) throws TasteException;
 
   /**
    * <p>Attaches a {@link PreferenceInferrer} to the {@link UserSimilarity} implementation.</p>

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/PreferenceTransform.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/PreferenceTransform.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/PreferenceTransform.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/PreferenceTransform.java Tue Aug  4 00:06:46 2009
@@ -29,6 +29,6 @@
  */
 public interface PreferenceTransform extends Refreshable {
 
-  double getTransformedValue(Preference pref) throws TasteException;
+  float getTransformedValue(Preference pref) throws TasteException;
 
 }
\ No newline at end of file

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/SimilarityTransform.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/SimilarityTransform.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/SimilarityTransform.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/transforms/SimilarityTransform.java Tue Aug  4 00:06:46 2009
@@ -21,8 +21,7 @@
 
 /**
  * <p>Implementations encapsulate some transformation on similarity values between two things, where things might be
- * {@link org.apache.mahout.cf.taste.model.User}s or {@link org.apache.mahout.cf.taste.model.Item}s or something
- * else.</p>
+ * IDs of users or items or something else.</p>
  */
 public interface SimilarityTransform<T> extends Refreshable {
 

Modified: lucene/mahout/trunk/core/src/main/java/org/apache/mahout/clustering/kmeans/KMeansDriver.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/clustering/kmeans/KMeansDriver.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/main/java/org/apache/mahout/clustering/kmeans/KMeansDriver.java (original)
+++ lucene/mahout/trunk/core/src/main/java/org/apache/mahout/clustering/kmeans/KMeansDriver.java Tue Aug  4 00:06:46 2009
@@ -16,8 +16,6 @@
  */
 package org.apache.mahout.clustering.kmeans;
 
-import java.io.IOException;
-
 import org.apache.commons.cli2.CommandLine;
 import org.apache.commons.cli2.Group;
 import org.apache.commons.cli2.Option;
@@ -46,6 +44,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+
 public class KMeansDriver {
 
   /** The name of the directory used to output final results. */

Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/LoadTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/LoadTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/LoadTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/LoadTest.java Tue Aug  4 00:06:46 2009
@@ -19,10 +19,11 @@
 
 import junit.textui.TestRunner;
 import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastMap;
 import org.apache.mahout.cf.taste.impl.common.RandomUtils;
 import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
 import org.apache.mahout.cf.taste.impl.model.GenericPreference;
-import org.apache.mahout.cf.taste.impl.model.GenericUser;
+import org.apache.mahout.cf.taste.impl.model.GenericUserPreferenceArray;
 import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
 import org.apache.mahout.cf.taste.impl.recommender.CachingRecommender;
 import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
@@ -30,8 +31,7 @@
 import org.apache.mahout.cf.taste.impl.recommender.slopeone.SlopeOneRecommender;
 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.User;
+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.ItemSimilarity;
@@ -42,6 +42,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -90,24 +91,22 @@
   }
 
   private DataModel createModel() {
-
     List<Comparable<?>> itemIDs = new ArrayList<Comparable<?>>(NUM_ITEMS);
     for (int i = 0; i < NUM_ITEMS; i++) {
       itemIDs.add(String.valueOf(i));
     }
-
-    List<User> users = new ArrayList<User>(NUM_USERS);
+    Map<Comparable<?>, PreferenceArray> data = new FastMap<Comparable<?>, PreferenceArray>(NUM_USERS);
     for (int i = 0; i < NUM_USERS; i++) {
+      String userID = String.valueOf(i);
+
       int numPrefs = random.nextInt(NUM_PREFS) + 1;
-      List<Preference> prefs = new ArrayList<Preference>(numPrefs);
+      PreferenceArray prefs = new GenericUserPreferenceArray(numPrefs);
       for (int j = 0; j < numPrefs; j++) {
-        prefs.add(new GenericPreference(null, itemIDs.get(random.nextInt(NUM_ITEMS)), random.nextDouble()));
+        prefs.set(j, new GenericPreference(userID, itemIDs.get(random.nextInt(NUM_ITEMS)), random.nextFloat()));
       }
-      GenericUser user = new GenericUser(String.valueOf(i), prefs);
-      users.add(user);
+      data.put(userID, prefs);
     }
-
-    return new GenericDataModel(users);
+    return new GenericDataModel(data);
   }
 
   private void doTestLoad(Recommender recommender, int allowedTimeSec)

Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/TasteTestCase.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/TasteTestCase.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/TasteTestCase.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/TasteTestCase.java Tue Aug  4 00:06:46 2009
@@ -18,17 +18,18 @@
 package org.apache.mahout.cf.taste.impl;
 
 import junit.framework.TestCase;
+import org.apache.mahout.cf.taste.impl.common.FastMap;
 import org.apache.mahout.cf.taste.impl.common.RandomUtils;
 import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
 import org.apache.mahout.cf.taste.impl.model.GenericPreference;
-import org.apache.mahout.cf.taste.impl.model.GenericUser;
+import org.apache.mahout.cf.taste.impl.model.GenericUserPreferenceArray;
 import org.apache.mahout.cf.taste.model.DataModel;
 import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 
 public abstract class TasteTestCase extends TestCase {
 
@@ -41,33 +42,31 @@
     RandomUtils.useTestSeed();
   }
 
-  public static User getUser(String userID, Double... values) {
-    List<Preference> prefs = new ArrayList<Preference>(values.length);
-    int i = 0;
-    for (Double value : values) {
-      if (value != null) {
-        prefs.add(new GenericPreference(null, String.valueOf(i), value));
+  public static DataModel getDataModel(Comparable<?>[] userIDs, Double[][] prefValues) {
+    Map<Comparable<?>, PreferenceArray> result = new FastMap<Comparable<?>, PreferenceArray>();
+    for (int i = 0; i < userIDs.length; i++) {
+      List<Preference> prefsList = new ArrayList<Preference>();
+      for (int j = 0; j < prefValues[i].length; j++) {
+        if (prefValues[i][j] != null) {
+          prefsList.add(new GenericPreference(userIDs[i], String.valueOf(j), prefValues[i][j].floatValue()));
+        }
+      }
+      if (!prefsList.isEmpty()) {
+        result.put(userIDs[i], new GenericUserPreferenceArray(prefsList));
       }
-      i++;
     }
-    return new GenericUser(userID, prefs);
-  }
-
-  public static DataModel getDataModel(User... users) {
-    return new GenericDataModel(Arrays.asList(users));
+    return new GenericDataModel(result);
   }
 
   public static DataModel getDataModel() {
-    return new GenericDataModel(getMockUsers());
-  }
-
-  public static List<User> getMockUsers() {
-    List<User> users = new ArrayList<User>(4);
-    users.add(getUser("test1", 0.1, 0.3));
-    users.add(getUser("test2", 0.2, 0.3, 0.3));
-    users.add(getUser("test3", 0.4, 0.3, 0.5));
-    users.add(getUser("test4", 0.7, 0.3, 0.8));
-    return users;
+    return getDataModel(
+            new Comparable<?>[] {"test1", "test2", "test3", "test4"},
+            new Double[][] {
+                    {0.1, 0.3},
+                    {0.2, 0.3, 0.3},
+                    {0.4, 0.3, 0.5},
+                    {0.7, 0.3, 0.8},
+            });
   }
 
 }

Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/model/file/FileDataModelTest.java Tue Aug  4 00:06:46 2009
@@ -24,7 +24,7 @@
 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.User;
+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;
@@ -100,11 +100,11 @@
 
   public void testTranspose() throws Exception {
     FileDataModel tModel = new FileDataModel(testFile, true);
-    User user = tModel.getUser("456");
-    assertNotNull("user is null and it shouldn't be", user);
-    Preference[] pref = tModel.getPreferencesForItemAsArray("A123");
+    PreferenceArray userPrefs = tModel.getPreferencesFromUser("456");
+    assertNotNull("user prefs are null and it shouldn't be", userPrefs);
+    PreferenceArray pref = tModel.getPreferencesForItem("A123");
     assertNotNull("pref is null and it shouldn't be", pref);
-    assertEquals("pref Size: " + pref.length + " is not: " + 3, 3, pref.length);
+    assertEquals("pref Size: " + pref.length() + " is not: " + 3, 3, pref.length());
   }
 
   public void testGetItems() throws Exception {
@@ -132,25 +132,15 @@
   }
 
   public void testPreferencesForItem() throws Exception {
-    Iterable<? extends Preference> prefs = model.getPreferencesForItem("456");
+    PreferenceArray prefs = model.getPreferencesForItem("456");
     assertNotNull(prefs);
-    Iterator<? extends Preference> it = prefs.iterator();
-    assertNotNull(it);
-    assertTrue(it.hasNext());
-    Preference pref1 = it.next();
-    assertEquals("A123", pref1.getUser().getID());
+    Preference pref1 = prefs.get(0);
+    assertEquals("A123", pref1.getUserID());
     assertEquals("456", pref1.getItemID());
-    assertTrue(it.hasNext());
-    Preference pref2 = it.next();
-    assertEquals("D456", pref2.getUser().getID());
+    Preference pref2 = prefs.get(1);
+    assertEquals("D456", pref2.getUserID());
     assertEquals("456", pref2.getItemID());
-    assertFalse(it.hasNext());
-    try {
-      it.next();
-      fail("Should throw NoSuchElementException");
-    } catch (NoSuchElementException nsee) {
-      // good
-    }
+    assertEquals(2, prefs.length());
   }
 
   public void testGetNumUsers() throws Exception {
@@ -164,16 +154,6 @@
     assertEquals(2, model.getNumUsersWithPreferenceFor("123", "234"));
   }
 
-  public void testSetPreference() throws Exception {
-    model.setPreference("A123", "456", 0.2);
-    assertEquals(0.2, model.getUser("A123").getPreferenceFor("456").getValue());
-  }
-
-  public void testRemovePreference() throws Exception {
-    model.removePreference("A123", "456");
-    assertNull(model.getUser("A123").getPreferenceFor("456"));
-  }
-
   public void testRefresh() throws Exception {
     final AtomicBoolean initialized = new AtomicBoolean(false);
     Runnable initializer = new Runnable() {

Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/DummySimilarity.java Tue Aug  4 00:06:46 2009
@@ -18,7 +18,8 @@
 package org.apache.mahout.cf.taste.impl.neighborhood;
 
 import org.apache.mahout.cf.taste.common.Refreshable;
-import org.apache.mahout.cf.taste.model.User;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.model.DataModel;
 import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
 import org.apache.mahout.cf.taste.similarity.PreferenceInferrer;
 import org.apache.mahout.cf.taste.similarity.UserSimilarity;
@@ -27,10 +28,16 @@
 
 final class DummySimilarity implements UserSimilarity, ItemSimilarity {
 
+  private final DataModel dataModel;
+
+  DummySimilarity(DataModel dataModel) {
+    this.dataModel = dataModel;
+  }
+
   @Override
-  public double userSimilarity(User user1, User user2) {
-    return 1.0 / Math.abs(user1.getPreferencesAsArray()[0].getValue() -
-        user2.getPreferencesAsArray()[0].getValue());
+  public double userSimilarity(Comparable<?> userID1, Comparable<?> userID2) throws TasteException {
+    return 1.0 / Math.abs(dataModel.getPreferencesFromUser(userID1).get(0).getValue() -
+        dataModel.getPreferencesFromUser(userID2).get(0).getValue());
   }
 
   @Override

Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/NearestNNeighborhoodTest.java Tue Aug  4 00:06:46 2009
@@ -18,49 +18,38 @@
 package org.apache.mahout.cf.taste.impl.neighborhood;
 
 import org.apache.mahout.cf.taste.impl.TasteTestCase;
-import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
 import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.User;
 
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 
 /** <p>Tests {@link NearestNUserNeighborhood}.</p> */
 public final class NearestNNeighborhoodTest extends TasteTestCase {
 
   public void testNeighborhood() throws Exception {
 
-    List<User> users = getMockUsers();
-    DataModel dataModel = new GenericDataModel(users);
+    DataModel dataModel = getDataModel();
 
-    Collection<User> neighborhood =
-        new NearestNUserNeighborhood(1, new DummySimilarity(), dataModel).getUserNeighborhood("test1");
+    Collection<Comparable<?>> neighborhood =
+        new NearestNUserNeighborhood(1, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test1");
     assertNotNull(neighborhood);
     assertEquals(1, neighborhood.size());
-    assertTrue(neighborhood.contains(users.get(1)));
+    assertTrue(neighborhood.contains("test2"));
 
-    Collection<User> neighborhood2 =
-        new NearestNUserNeighborhood(2, new DummySimilarity(), dataModel).getUserNeighborhood("test2");
+    Collection<Comparable<?>> neighborhood2 =
+        new NearestNUserNeighborhood(2, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test2");
     assertNotNull(neighborhood2);
     assertEquals(2, neighborhood2.size());
-    assertTrue(neighborhood2.contains(users.get(0)));
-    assertTrue(neighborhood2.contains(users.get(2)));
+    assertTrue(neighborhood2.contains("test1"));
+    assertTrue(neighborhood2.contains("test3"));
 
-    Collection<User> neighborhood3 =
-        new NearestNUserNeighborhood(4, new DummySimilarity(), dataModel).getUserNeighborhood("test4");
+    Collection<Comparable<?>> neighborhood3 =
+        new NearestNUserNeighborhood(4, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test4");
     assertNotNull(neighborhood3);
     assertEquals(3, neighborhood3.size());
-    assertTrue(neighborhood3.contains(users.get(0)));
-    assertTrue(neighborhood3.contains(users.get(1)));
-    assertTrue(neighborhood3.contains(users.get(2)));
+    assertTrue(neighborhood3.contains("test1"));
+    assertTrue(neighborhood3.contains("test2"));
+    assertTrue(neighborhood3.contains("test3"));
 
   }
 
-  public void testRefresh() throws Exception {
-    // Make sure this doesn't throw an exception
-    DataModel dataModel = new GenericDataModel(Collections.singletonList(getUser("test1", 0.1)));
-    new NearestNUserNeighborhood(1, new DummySimilarity(), dataModel).refresh(null);
-  }
-
 }

Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/neighborhood/ThresholdNeighborhoodTest.java Tue Aug  4 00:06:46 2009
@@ -18,47 +18,36 @@
 package org.apache.mahout.cf.taste.impl.neighborhood;
 
 import org.apache.mahout.cf.taste.impl.TasteTestCase;
-import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
 import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.User;
 
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 
 /** <p>Tests {@link ThresholdUserNeighborhood}.</p> */
 public final class ThresholdNeighborhoodTest extends TasteTestCase {
 
   public void testNeighborhood() throws Exception {
 
-    List<User> users = getMockUsers();
-    DataModel dataModel = new GenericDataModel(users);
+    DataModel dataModel = getDataModel();
 
-    Collection<User> neighborhood =
-        new ThresholdUserNeighborhood(20.0, new DummySimilarity(), dataModel).getUserNeighborhood("test1");
+    Collection<Comparable<?>> neighborhood =
+        new ThresholdUserNeighborhood(19.0, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test1");
     assertNotNull(neighborhood);
     assertTrue(neighborhood.isEmpty());
 
-    Collection<User> neighborhood2 =
-        new ThresholdUserNeighborhood(10.0, new DummySimilarity(), dataModel).getUserNeighborhood("test1");
+    Collection<Comparable<?>> neighborhood2 =
+        new ThresholdUserNeighborhood(9.0, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test1");
     assertNotNull(neighborhood2);
     assertEquals(1, neighborhood2.size());
-    assertTrue(neighborhood2.contains(users.get(1)));
+    assertTrue(neighborhood2.contains("test2"));
 
-    Collection<User> neighborhood3 =
-        new ThresholdUserNeighborhood(1.0, new DummySimilarity(), dataModel).getUserNeighborhood("test2");
+    Collection<Comparable<?>> neighborhood3 =
+        new ThresholdUserNeighborhood(0.9, new DummySimilarity(dataModel), dataModel).getUserNeighborhood("test2");
     assertNotNull(neighborhood3);
     assertEquals(3, neighborhood3.size());
-    assertTrue(neighborhood3.contains(users.get(0)));
-    assertTrue(neighborhood3.contains(users.get(2)));
-    assertTrue(neighborhood3.contains(users.get(3)));
+    assertTrue(neighborhood3.contains("test1"));
+    assertTrue(neighborhood3.contains("test3"));
+    assertTrue(neighborhood3.contains("test4"));
 
   }
 
-  public void testRefresh() throws Exception {
-    // Make sure this doesn't throw an exception
-    DataModel dataModel = new GenericDataModel(Collections.singletonList(getUser("test1", 0.1)));
-    new ThresholdUserNeighborhood(20.0, new DummySimilarity(), dataModel).refresh(null);
-  }
-
 }

Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommenderTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommenderTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommenderTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericItemBasedRecommenderTest.java Tue Aug  4 00:06:46 2009
@@ -18,10 +18,8 @@
 package org.apache.mahout.cf.taste.impl.recommender;
 
 import org.apache.mahout.cf.taste.impl.TasteTestCase;
-import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
 import org.apache.mahout.cf.taste.impl.similarity.GenericItemSimilarity;
 import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.User;
 import org.apache.mahout.cf.taste.recommender.ItemBasedRecommender;
 import org.apache.mahout.cf.taste.recommender.RecommendedItem;
 import org.apache.mahout.cf.taste.recommender.Recommender;
@@ -48,13 +46,17 @@
   }
 
   public void testHowMany() throws Exception {
-    List<User> users = new ArrayList<User>(3);
-    users.add(getUser("test1", 0.1, 0.2));
-    users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
-    users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
-    users.add(getUser("test4", 0.1, 0.4, 0.5, 0.8, 0.9, 1.0));
-    users.add(getUser("test5", 0.2, 0.3, 0.6, 0.7, 0.1, 0.2));
-    DataModel dataModel = new GenericDataModel(users);
+
+    DataModel dataModel = getDataModel(
+            new Comparable<?>[] {"test1", "test2", "test3", "test4", "test5"},
+            new Double[][] {
+                    {0.1, 0.2},
+                    {0.2, 0.3, 0.3, 0.6},
+                    {0.4, 0.4, 0.5, 0.9},
+                    {0.1, 0.4, 0.5, 0.8, 0.9, 1.0},
+                    {0.2, 0.3, 0.6, 0.7, 0.1, 0.2},
+            });
+
     Collection<GenericItemSimilarity.ItemItemSimilarity> similarities =
         new ArrayList<GenericItemSimilarity.ItemItemSimilarity>(6);
     for (int i = 0; i < 6; i++) {
@@ -79,11 +81,15 @@
   }
 
   public void testRescorer() throws Exception {
-    List<User> users = new ArrayList<User>(3);
-    users.add(getUser("test1", 0.1, 0.2));
-    users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
-    users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
-    DataModel dataModel = new GenericDataModel(users);
+
+    DataModel dataModel = getDataModel(
+            new Comparable<?>[] {"test1", "test2", "test3"},
+            new Double[][] {
+                    {0.1, 0.2},
+                    {0.2, 0.3, 0.3, 0.6},
+                    {0.4, 0.4, 0.5, 0.9},
+            });
+
     Comparable<?> item1 = "0";
     Comparable<?> item2 = "1";
     Comparable<?> item3 = "2";
@@ -175,7 +181,7 @@
   }
 
   private static ItemBasedRecommender buildRecommender() {
-    DataModel dataModel = new GenericDataModel(getMockUsers());
+    DataModel dataModel = getDataModel();
     Collection<GenericItemSimilarity.ItemItemSimilarity> similarities =
         new ArrayList<GenericItemSimilarity.ItemItemSimilarity>(2);
     Comparable<?> item1 = "0";
@@ -188,12 +194,16 @@
   }
 
   private static ItemBasedRecommender buildRecommender2() {
-    List<User> users = new ArrayList<User>(4);
-    users.add(getUser("test1", 0.1, 0.3, 0.9, 0.8));
-    users.add(getUser("test2", 0.2, 0.3, 0.3, 0.4));
-    users.add(getUser("test3", 0.4, 0.3, 0.5, 0.1, 0.1));
-    users.add(getUser("test4", 0.7, 0.3, 0.8, 0.5, 0.6));
-    DataModel dataModel = new GenericDataModel(users);
+
+    DataModel dataModel = getDataModel(
+        new Comparable<?>[] {"test1", "test2", "test3", "test4"},
+        new Double[][] {
+                {0.1, 0.3, 0.9, 0.8},
+                {0.2, 0.3, 0.3, 0.4},
+                {0.4, 0.3, 0.5, 0.1, 0.1},
+                {0.7, 0.3, 0.8, 0.5, 0.6},
+        });
+
     Collection<GenericItemSimilarity.ItemItemSimilarity> similarities =
         new ArrayList<GenericItemSimilarity.ItemItemSimilarity>(10);
     Comparable<?> item1 = "0";

Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommenderTest.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommenderTest.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommenderTest.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/GenericUserBasedRecommenderTest.java Tue Aug  4 00:06:46 2009
@@ -18,18 +18,15 @@
 package org.apache.mahout.cf.taste.impl.recommender;
 
 import org.apache.mahout.cf.taste.impl.TasteTestCase;
-import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
 import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
 import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
 import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.User;
 import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
 import org.apache.mahout.cf.taste.recommender.RecommendedItem;
 import org.apache.mahout.cf.taste.recommender.Recommender;
 import org.apache.mahout.cf.taste.recommender.UserBasedRecommender;
 import org.apache.mahout.cf.taste.similarity.UserSimilarity;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
@@ -43,20 +40,22 @@
     assertEquals(1, recommended.size());
     RecommendedItem firstRecommended = recommended.get(0);
     assertEquals("2", firstRecommended.getItemID());
-    assertEquals(0.3, firstRecommended.getValue());
+    assertEquals(0.3f, firstRecommended.getValue());
     recommender.refresh(null);
     assertEquals("2", firstRecommended.getItemID());
-    assertEquals(0.3, firstRecommended.getValue());
+    assertEquals(0.3f, firstRecommended.getValue());
   }
 
   public void testHowMany() throws Exception {
-    List<User> users = new ArrayList<User>(3);
-    users.add(getUser("test1", 0.1, 0.2));
-    users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
-    users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
-    users.add(getUser("test4", 0.1, 0.4, 0.5, 0.8, 0.9, 1.0));
-    users.add(getUser("test5", 0.2, 0.3, 0.6, 0.7, 0.1, 0.2));
-    DataModel dataModel = new GenericDataModel(users);
+    DataModel dataModel = getDataModel(
+            new Comparable<?>[] {"test1", "test2", "test3", "test4", "test5"},
+            new Double[][] {
+                    {0.1, 0.2},
+                    {0.2, 0.3, 0.3, 0.6},
+                    {0.4, 0.4, 0.5, 0.9},
+                    {0.1, 0.4, 0.5, 0.8, 0.9, 1.0},
+                    {0.2, 0.3, 0.6, 0.7, 0.1, 0.2},
+            });
     UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
     UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, dataModel);
     Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
@@ -72,11 +71,13 @@
   }
 
   public void testRescorer() throws Exception {
-    List<User> users = new ArrayList<User>(3);
-    users.add(getUser("test1", 0.1, 0.2));
-    users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
-    users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
-    DataModel dataModel = new GenericDataModel(users);
+    DataModel dataModel = getDataModel(
+            new Comparable<?>[] {"test1", "test2", "test3"},
+            new Double[][] {
+                    {0.1, 0.2},
+                    {0.2, 0.3, 0.3, 0.6},
+                    {0.4, 0.4, 0.5, 0.9},
+            });
     UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
     UserNeighborhood neighborhood = new NearestNUserNeighborhood(1, similarity, dataModel);
     Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
@@ -93,7 +94,7 @@
 
   public void testEstimatePref() throws Exception {
     Recommender recommender = buildRecommender();
-    assertEquals(0.3, recommender.estimatePreference("test1", "2"));
+    assertEquals(0.3f, recommender.estimatePreference("test1", "2"));
   }
 
   public void testBestRating() throws Exception {
@@ -104,37 +105,37 @@
     RecommendedItem firstRecommended = recommended.get(0);
     // item one should be recommended because it has a greater rating/score
     assertEquals("2", firstRecommended.getItemID());
-    assertEquals(0.3, firstRecommended.getValue(), EPSILON);
+    assertEquals(0.3f, firstRecommended.getValue(), EPSILON);
   }
 
   public void testMostSimilar() throws Exception {
     UserBasedRecommender recommender = buildRecommender();
-    List<User> similar = recommender.mostSimilarUsers("test1", 2);
+    List<Comparable<?>> similar = recommender.mostSimilarUserIDs("test1", 2);
     assertNotNull(similar);
     assertEquals(2, similar.size());
-    User first = similar.get(0);
-    User second = similar.get(1);
-    assertEquals("test2", first.getID());
-    assertEquals("test3", second.getID());
+    assertEquals("test2", similar.get(0));
+    assertEquals("test4", similar.get(1));
   }
 
   public void testIsolatedUser() throws Exception {
-    List<User> users = new ArrayList<User>(3);
-    users.add(getUser("test1", 0.1, 0.2));
-    users.add(getUser("test2", 0.2, 0.3, 0.3, 0.6));
-    users.add(getUser("test3", 0.4, 0.4, 0.5, 0.9));
-    users.add(getUser("test4"));
-    DataModel dataModel = new GenericDataModel(users);
+    DataModel dataModel = getDataModel(
+            new Comparable<?>[] {"test1", "test2", "test3", "test4"},
+            new Double[][] {
+                    {0.1, 0.2},
+                    {0.2, 0.3, 0.3, 0.6},
+                    {0.4, 0.4, 0.5, 0.9},
+                    {null, null, null, null, 1.0},
+            });
     UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
     UserNeighborhood neighborhood = new NearestNUserNeighborhood(3, similarity, dataModel);
     UserBasedRecommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
-    Collection<User> mostSimilar = recommender.mostSimilarUsers("test4", 3);
+    Collection<Comparable<?>> mostSimilar = recommender.mostSimilarUserIDs("test4", 3);
     assertNotNull(mostSimilar);
     assertEquals(0, mostSimilar.size());
   }
 
   private static UserBasedRecommender buildRecommender() throws Exception {
-    DataModel dataModel = new GenericDataModel(getMockUsers());
+    DataModel dataModel = getDataModel();
     UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
     UserNeighborhood neighborhood = new NearestNUserNeighborhood(1, similarity, dataModel);
     return new GenericUserBasedRecommender(dataModel, neighborhood, similarity);

Modified: lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/MockRecommender.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/MockRecommender.java?rev=800634&r1=800633&r2=800634&view=diff
==============================================================================
--- lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/MockRecommender.java (original)
+++ lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/MockRecommender.java Tue Aug  4 00:06:46 2009
@@ -18,16 +18,12 @@
 package org.apache.mahout.cf.taste.impl.recommender;
 
 import org.apache.mahout.cf.taste.common.Refreshable;
-import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
-import org.apache.mahout.cf.taste.impl.model.GenericUser;
+import org.apache.mahout.cf.taste.impl.TasteTestCase;
 import org.apache.mahout.cf.taste.model.DataModel;
-import org.apache.mahout.cf.taste.model.Preference;
-import org.apache.mahout.cf.taste.model.User;
 import org.apache.mahout.cf.taste.recommender.RecommendedItem;
 import org.apache.mahout.cf.taste.recommender.Recommender;
 import org.apache.mahout.cf.taste.recommender.Rescorer;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -46,7 +42,7 @@
   public List<RecommendedItem> recommend(Comparable<?> userID, int howMany) {
     recommendCount.incrementAndGet();
     return Collections.<RecommendedItem>singletonList(
-        new GenericRecommendedItem("1", 1.0));
+        new GenericRecommendedItem("1", 1.0f));
   }
 
   @Override
@@ -57,13 +53,13 @@
   }
 
   @Override
-  public double estimatePreference(Comparable<?> userID, Comparable<?> itemID) {
+  public float estimatePreference(Comparable<?> userID, Comparable<?> itemID) {
     recommendCount.incrementAndGet();
-    return 0.0;
+    return 0.0f;
   }
 
   @Override
-  public void setPreference(Comparable<?> userID, Comparable<?> itemID, double value) {
+  public void setPreference(Comparable<?> userID, Comparable<?> itemID, float value) {
     // do nothing
   }
 
@@ -74,14 +70,9 @@
 
   @Override
   public DataModel getDataModel() {
-    User user1 = new GenericUser("1", Collections.<Preference>emptyList());
-    User user2 = new GenericUser("2", Collections.<Preference>emptyList());
-    User user3 = new GenericUser("3", Collections.<Preference>emptyList());
-    List<User> users = new ArrayList<User>(3);
-    users.add(user1);
-    users.add(user2);
-    users.add(user3);
-    return new GenericDataModel(users);
+    return TasteTestCase.getDataModel(
+            new Comparable<?>[] {"1","2","3"},
+            new Double[][]{{1.0},{2.0},{3.0}});
   }
 
   @Override