@Override
 public void setPreference(long userID, long itemID, float value) throws TasteException {
   DataModel dataModel = getDataModel();
   double prefDelta;
   try {
     Float oldPref = dataModel.getPreferenceValue(userID, itemID);
     prefDelta = oldPref == null ? value : value - oldPref;
   } catch (NoSuchUserException nsee) {
     prefDelta = value;
   }
   super.setPreference(userID, itemID, value);
   try {
     buildAveragesLock.writeLock().lock();
     RunningAverage itemAverage = itemAverages.get(itemID);
     if (itemAverage == null) {
       RunningAverage newItemAverage = new FullRunningAverage();
       newItemAverage.addDatum(prefDelta);
       itemAverages.put(itemID, newItemAverage);
     } else {
       itemAverage.changeDatum(prefDelta);
     }
     RunningAverage userAverage = userAverages.get(userID);
     if (userAverage == null) {
       RunningAverage newUserAveragae = new FullRunningAverage();
       newUserAveragae.addDatum(prefDelta);
       userAverages.put(userID, newUserAveragae);
     } else {
       userAverage.changeDatum(prefDelta);
     }
     overallAveragePrefValue.changeDatum(prefDelta);
   } finally {
     buildAveragesLock.writeLock().unlock();
   }
 }
 private static void addDatumAndCreateIfNeeded(
     long itemID, float value, FastByIDMap<RunningAverage> averages) {
   RunningAverage itemAverage = averages.get(itemID);
   if (itemAverage == null) {
     itemAverage = new FullRunningAverage();
     averages.put(itemID, itemAverage);
   }
   itemAverage.addDatum(value);
 }
 private void buildAverageDiffs() throws TasteException {
   try {
     buildAveragesLock.writeLock().lock();
     DataModel dataModel = getDataModel();
     LongPrimitiveIterator it = dataModel.getUserIDs();
     while (it.hasNext()) {
       long userID = it.nextLong();
       PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
       int size = prefs.length();
       for (int i = 0; i < size; i++) {
         long itemID = prefs.getItemID(i);
         float value = prefs.getValue(i);
         addDatumAndCreateIfNeeded(itemID, value, itemAverages);
         addDatumAndCreateIfNeeded(userID, value, userAverages);
         overallAveragePrefValue.addDatum(value);
       }
     }
   } finally {
     buildAveragesLock.writeLock().unlock();
   }
 }