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 2010/11/27 12:17:53 UTC
svn commit: r1039653 - in
/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl:
common/RefreshRunnable.java model/jdbc/ReloadFromJDBCDataModel.java
Author: srowen
Date: Sat Nov 27 11:17:52 2010
New Revision: 1039653
URL: http://svn.apache.org/viewvc?rev=1039653&view=rev
Log:
Utility classes useful in periodically reloading DB data into memory, for simple recommenders
Added:
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshRunnable.java
mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/ReloadFromJDBCDataModel.java
Added: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshRunnable.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshRunnable.java?rev=1039653&view=auto
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshRunnable.java (added)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/common/RefreshRunnable.java Sat Nov 27 11:17:52 2010
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.cf.taste.impl.common;
+
+import com.google.common.base.Preconditions;
+import org.apache.mahout.cf.taste.common.Refreshable;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Simply calls {@linkRefreshable#refresh(java.util.Collection)} on a {@link Refreshable}.
+ */
+public final class RefreshRunnable implements Runnable, Callable<Void> {
+
+ private final Refreshable refreshable;
+
+ public RefreshRunnable(Refreshable refreshable) {
+ Preconditions.checkNotNull(refreshable);
+ this.refreshable = refreshable;
+ }
+
+ @Override
+ public void run() {
+ refreshable.refresh(null);
+ }
+
+ @Override
+ public Void call() {
+ run();
+ return null;
+ }
+
+}
Added: mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/ReloadFromJDBCDataModel.java
URL: http://svn.apache.org/viewvc/mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/ReloadFromJDBCDataModel.java?rev=1039653&view=auto
==============================================================================
--- mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/ReloadFromJDBCDataModel.java (added)
+++ mahout/trunk/core/src/main/java/org/apache/mahout/cf/taste/impl/model/jdbc/ReloadFromJDBCDataModel.java Sat Nov 27 11:17:52 2010
@@ -0,0 +1,159 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mahout.cf.taste.impl.model.jdbc;
+
+import com.google.common.base.Preconditions;
+import org.apache.mahout.cf.taste.common.Refreshable;
+import org.apache.mahout.cf.taste.common.TasteException;
+import org.apache.mahout.cf.taste.impl.common.FastIDSet;
+import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
+import org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel;
+import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
+import org.apache.mahout.cf.taste.model.DataModel;
+import org.apache.mahout.cf.taste.model.JDBCDataModel;
+import org.apache.mahout.cf.taste.model.PreferenceArray;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+
+/**
+ * A {@link DataModel} which loads, and can re-load, data from a JDBC-backed {@link JDBCDataModel} into memory, as a
+ * {@link GenericDataModel} or {@link GenericBooleanPrefDataModel}. It is intended to provide the speed
+ * advantage of in-memory representation but be able to update periodically to pull in new data from a database source.
+ */
+public final class ReloadFromJDBCDataModel implements DataModel {
+
+ private static final Logger log = LoggerFactory.getLogger(ReloadFromJDBCDataModel.class);
+
+ private DataModel delegateInMemory;
+ private final JDBCDataModel delegate;
+
+ public ReloadFromJDBCDataModel(JDBCDataModel delegate) throws TasteException {
+ Preconditions.checkNotNull(delegate);
+ this.delegate = delegate;
+ refresh(null);
+ if (delegateInMemory == null) {
+ throw new TasteException("Failed to load data into memory");
+ }
+ }
+
+ @Override
+ public void refresh(Collection<Refreshable> alreadyRefreshed) {
+ delegate.refresh(alreadyRefreshed);
+ try {
+ // Load new in-memory representation,
+ log.info("Loading new JDBC delegate data...");
+ DataModel newDelegateInMemory = delegate.hasPreferenceValues() ?
+ new GenericDataModel(delegate.exportWithPrefs()) :
+ new GenericBooleanPrefDataModel(delegate.exportWithIDsOnly());
+ // and then swap to it.
+ log.info("New data loaded.");
+ delegateInMemory = newDelegateInMemory;
+ } catch (TasteException te) {
+ log.warn("Error while reloading JDBC delegate data", te);
+ // But continue with whatever is loaded
+ }
+ }
+
+ public JDBCDataModel getDelegate() {
+ return delegate;
+ }
+
+ public DataModel getDelegateInMemory() {
+ return delegateInMemory;
+ }
+
+ // Delegated methods:
+
+ @Override
+ public LongPrimitiveIterator getUserIDs() throws TasteException {
+ return delegateInMemory.getUserIDs();
+ }
+
+ @Override
+ public PreferenceArray getPreferencesFromUser(long id) throws TasteException {
+ return delegateInMemory.getPreferencesFromUser(id);
+ }
+
+ @Override
+ public FastIDSet getItemIDsFromUser(long id) throws TasteException {
+ return delegateInMemory.getItemIDsFromUser(id);
+ }
+
+ @Override
+ public Float getPreferenceValue(long userID, long itemID) throws TasteException {
+ return delegateInMemory.getPreferenceValue(userID, itemID);
+ }
+
+ @Override
+ public Long getPreferenceTime(long userID, long itemID) throws TasteException {
+ return delegateInMemory.getPreferenceTime(userID, itemID);
+ }
+
+ @Override
+ public LongPrimitiveIterator getItemIDs() throws TasteException {
+ return delegateInMemory.getItemIDs();
+ }
+
+ @Override
+ public PreferenceArray getPreferencesForItem(long itemID) throws TasteException {
+ return delegateInMemory.getPreferencesForItem(itemID);
+ }
+
+ @Override
+ public int getNumItems() throws TasteException {
+ return delegateInMemory.getNumItems();
+ }
+
+ @Override
+ public int getNumUsers() throws TasteException {
+ return delegateInMemory.getNumUsers();
+ }
+
+ @Override
+ public int getNumUsersWithPreferenceFor(long... itemIDs) throws TasteException {
+ return delegateInMemory.getNumUsersWithPreferenceFor(itemIDs);
+ }
+
+ @Override
+ public void setPreference(long userID, long itemID, float value) throws TasteException {
+ delegateInMemory.setPreference(userID, itemID, value);
+ }
+
+ @Override
+ public void removePreference(long userID, long itemID) throws TasteException {
+ delegateInMemory.removePreference(userID, itemID);
+ }
+
+ @Override
+ public boolean hasPreferenceValues() {
+ return delegateInMemory.hasPreferenceValues();
+ }
+
+ @Override
+ public float getMaxPreference() {
+ return delegateInMemory.getMaxPreference();
+ }
+
+ @Override
+ public float getMinPreference() {
+ return delegateInMemory.getMinPreference();
+ }
+
+}