Author: srowen
Date: Fri Oct 31 12:02:53 2008
New Revision: 709534

URL: http://svn.apache.org/viewvc?rev=709534&view=rev
Log:
Allow CachingRecommender to cache rescored entries as long as the Rescorer does 
not change

Modified:
    
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommender.java
    
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java

Modified: 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommender.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommender.java?rev=709534&r1=709533&r2=709534&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommender.java
 (original)
+++ 
lucene/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommender.java
 Fri Oct 31 12:02:53 2008
@@ -52,6 +52,7 @@
   private final Cache<Object, Recommendations> recommendationCache;
   private final Cache<Pair<?, ?>, Double> estimatedPrefCache;
   private final RefreshHelper refreshHelper;
+  private Rescorer<Item> currentRescorer;
 
   public CachingRecommender(Recommender recommender) throws TasteException {
     if (recommender == null) {
@@ -62,9 +63,7 @@
     // Use "num users" as an upper limit on cache size. Rough guess.
     int numUsers = recommender.getDataModel().getNumUsers();
     this.recommendationCache =
-            new Cache<Object, Recommendations>(
-                    new RecommendationRetriever(this.recommender, 
this.maxHowMany),
-                    numUsers);
+        new Cache<Object, Recommendations>(new 
RecommendationRetriever(this.recommender), numUsers);
     this.estimatedPrefCache =
             new Cache<Pair<?, ?>, Double>(new 
EstimatedPrefRetriever(this.recommender), numUsers);
     this.refreshHelper = new RefreshHelper(new Callable<Object>() {
@@ -76,9 +75,28 @@
     this.refreshHelper.addDependency(recommender);
   }
 
+  private synchronized void setCurrentRescorer(Rescorer<Item> rescorer) {
+    if (rescorer == null) {
+      if (currentRescorer != null) {
+        currentRescorer = null;
+        clear();
+      }
+    } else {
+      if (!rescorer.equals(currentRescorer)) {
+        currentRescorer = rescorer;
+        clear();
+      }
+    }
+  }
+
   public List<RecommendedItem> recommend(Object userID, int howMany) throws 
TasteException {
+    return recommend(userID, howMany, null);
+  }
+
+  public List<RecommendedItem> recommend(Object userID, int howMany, 
Rescorer<Item> rescorer)
+          throws TasteException {
     if (userID == null) {
-      throw new IllegalArgumentException("user ID is null");
+      throw new IllegalArgumentException("userID is null");
     }
     if (howMany < 1) {
       throw new IllegalArgumentException("howMany must be at least 1");
@@ -90,6 +108,8 @@
       }
     }
 
+    setCurrentRescorer(rescorer);
+
     Recommendations recommendations = recommendationCache.get(userID);
     if (recommendations.getItems().size() < howMany && 
!recommendations.noMoreRecommendableItems) {
       clear(userID);
@@ -104,12 +124,6 @@
            recommendations.getItems();
   }
 
-  public List<RecommendedItem> recommend(Object userID, int howMany, 
Rescorer<Item> rescorer)
-          throws TasteException {
-    // Hmm, hard to recommendationCache this since the rescorer may change
-    return recommender.recommend(userID, howMany, rescorer);
-  }
-
   public double estimatePreference(Object userID, Object itemID) throws 
TasteException {
     return estimatedPrefCache.get(new Pair<Object, Object>(userID, itemID));
   }
@@ -155,19 +169,18 @@
     return "CachingRecommender[recommender:" + recommender + ']';
   }
 
-  private static final class RecommendationRetriever implements 
Retriever<Object, Recommendations> {
+  private final class RecommendationRetriever implements Retriever<Object, 
Recommendations> {
 
     private final Recommender recommender;
-    private final AtomicInteger maxHowMany;
 
-    private RecommendationRetriever(Recommender recommender, AtomicInteger 
maxHowMany) {
+    private RecommendationRetriever(Recommender recommender) {
       this.recommender = recommender;
-      this.maxHowMany = maxHowMany;
     }
 
     public Recommendations get(Object key) throws TasteException {
       log.debug("Retrieving new recommendations for user ID '{}'", key);
-      return new 
Recommendations(Collections.unmodifiableList(recommender.recommend(key, 
maxHowMany.get())));
+      return new Recommendations(
+          Collections.unmodifiableList(recommender.recommend(key, 
maxHowMany.get(), currentRescorer)));
     }
   }
 

Modified: 
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java
URL: 
http://svn.apache.org/viewvc/lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java?rev=709534&r1=709533&r2=709534&view=diff
==============================================================================
--- 
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java
 (original)
+++ 
lucene/mahout/trunk/core/src/test/java/org/apache/mahout/cf/taste/impl/recommender/CachingRecommenderTest.java
 Fri Oct 31 12:02:53 2008
@@ -50,7 +50,7 @@
     cachingRecommender.recommend("3", 1);
     assertEquals(5, recommendCount.get());
 
-    // Results from this recommend() method can't be cached:
+    // Results from this recommend() method can be cached...
     Rescorer<Item> rescorer = NullRescorer.getItemInstance();
     cachingRecommender.refresh(null);
     cachingRecommender.recommend("1", 1, rescorer);
@@ -58,8 +58,14 @@
     cachingRecommender.recommend("2", 1, rescorer);
     assertEquals(7, recommendCount.get());
     cachingRecommender.recommend("1", 1, rescorer);
-    assertEquals(8, recommendCount.get());
+    assertEquals(7, recommendCount.get());
     cachingRecommender.recommend("2", 1, rescorer);
+    assertEquals(7, recommendCount.get());
+
+    // until you switch Rescorers
+    cachingRecommender.recommend("1", 1, null);
+    assertEquals(8, recommendCount.get());
+    cachingRecommender.recommend("2", 1, null);
     assertEquals(9, recommendCount.get());
 
     cachingRecommender.refresh(null);


Reply via email to