Bug 459246 - introduced ICalculatedValueCache interface to be able to
exchange the caching implementation for summary and groupby summary
values
Change-Id: Ib1e2df32699ef9f800400bb0c6dabf53b7667512
Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com>
diff --git a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/util/CalculatedValueCacheTest.java b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/util/CalculatedValueCacheTest.java
index 0b6e3fc..d131ca4 100644
--- a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/util/CalculatedValueCacheTest.java
+++ b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/util/CalculatedValueCacheTest.java
@@ -24,7 +24,7 @@
*/
public class CalculatedValueCacheTest {
- CalculatedValueCache valueCache;
+ ICalculatedValueCache valueCache;
ICalculator calculator = new ICalculator() {
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/summaryrow/SummaryRowLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/summaryrow/SummaryRowLayer.java
index 577005e..ac833a0 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/summaryrow/SummaryRowLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/summaryrow/SummaryRowLayer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2013 Original authors and others.
+ * Copyright (c) 2012, 2013, 2015 Original authors and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* Original authors and others - initial API and implementation
+ * Dirk Fauth <dirk.fauth@googlemail.com> - Bug 459246
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.summaryrow;
@@ -30,6 +31,7 @@
import org.eclipse.nebula.widgets.nattable.summaryrow.command.CalculateSummaryRowValuesCommand;
import org.eclipse.nebula.widgets.nattable.util.ArrayUtil;
import org.eclipse.nebula.widgets.nattable.util.CalculatedValueCache;
+import org.eclipse.nebula.widgets.nattable.util.ICalculatedValueCache;
import org.eclipse.nebula.widgets.nattable.util.ICalculator;
/**
@@ -82,7 +84,7 @@
* The value cache that contains the summary values and performs summary
* calculation in background processes if necessary.
*/
- private CalculatedValueCache valueCache;
+ private ICalculatedValueCache valueCache;
/**
* Converter that is used to ensure the row height of the summary row is
* scaled correctly.
@@ -488,4 +490,32 @@
public void setStandalone(boolean standalone) {
this.standalone = standalone;
}
+
+ /**
+ * @return The {@link ICalculatedValueCache} that contains the summary
+ * values and performs summary calculation in background processes
+ * if necessary.
+ */
+ public ICalculatedValueCache getValueCache() {
+ return this.valueCache;
+ }
+
+ /**
+ * Set the {@link ICalculatedValueCache} that should be used internally to
+ * calculate the summary values in a background thread and cache the
+ * results.
+ * <p>
+ * <b><u>Note:</u></b> By default the {@link CalculatedValueCache} is used.
+ * Be sure you know what you are doing when you are trying to exchange the
+ * implementation.
+ * </p>
+ *
+ * @param valueCache
+ * The {@link ICalculatedValueCache} that contains the summary
+ * values and performs summary calculation in background
+ * processes if necessary.
+ */
+ public void setValueCache(ICalculatedValueCache valueCache) {
+ this.valueCache = valueCache;
+ }
}
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/util/CalculatedValueCache.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/util/CalculatedValueCache.java
index b9a68af..eee604b 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/util/CalculatedValueCache.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/util/CalculatedValueCache.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Dirk Fauth and others.
+ * Copyright (c) 2014, 2015 Dirk Fauth and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
* Roman Flueckiger <roman.flueckiger@mac.com - switched to concurrent hash maps to prevent a concurrency issue
+ * Dirk Fauth <dirk.fauth@googlemail.com> - Bug 459246
*******************************************************************************/
package org.eclipse.nebula.widgets.nattable.util;
@@ -29,10 +30,8 @@
* {@link ICalculatedValueCacheKey} as the key for the value cache. Usually the
* internal default implementations for column or row position, or the
* column-row coordinates should fit most of the use cases.
- *
- * @author Dirk Fauth
*/
-public class CalculatedValueCache {
+public class CalculatedValueCache implements ICalculatedValueCache {
/**
* The ILayer this value cache is connected to. Needed to perform cell
@@ -114,8 +113,7 @@
* Flag to specify if the row position should be used as cache
* key.
*/
- public CalculatedValueCache(ILayer layer, boolean useColumnAsKey,
- boolean useRowAsKey) {
+ public CalculatedValueCache(ILayer layer, boolean useColumnAsKey, boolean useRowAsKey) {
this(layer, useColumnAsKey, useRowAsKey, true);
}
@@ -146,8 +144,7 @@
* Flag to specify if the update of the calculated values should
* be performed smoothly.
*/
- public CalculatedValueCache(ILayer layer, boolean useColumnAsKey,
- boolean useRowAsKey, boolean smoothUpdates) {
+ public CalculatedValueCache(ILayer layer, boolean useColumnAsKey, boolean useRowAsKey, boolean smoothUpdates) {
this.layer = layer;
this.executor = Executors.newCachedThreadPool();
@@ -156,36 +153,9 @@
this.smoothUpdates = smoothUpdates;
}
- /**
- * Returns the calculated value for the specified column and row position.
- * If there is no calculated value for that coordinates in the cache or
- * there is a potentially stale value, the re-calculation of the value is
- * executed.
- * <p>
- * This method tries to use a predefined cache key dependent on the
- * configuration of this CalculatedValueCache.
- *
- * @param columnPosition
- * The column position of the requested value.
- * @param rowPosition
- * The row position of the requested value.
- * @param calculateInBackground
- * Flag to specify whether the value calculation should be
- * processed in the background or not. Setting this value to
- * <code>false</code> will cause calculation in the UI thread,
- * which is usually necessary in case of exporting and printing.
- * @param calculator
- * The {@link ICalculator} that is used for calculating the
- * values.
- * @return The value for the given coordinates.
- *
- * @throws IllegalStateException
- * if this CalculatedValueCache is configured to not use the
- * column and row position for cache key definition.
- */
- public Object getCalculatedValue(final int columnPosition,
- final int rowPosition, boolean calculateInBackground,
- final ICalculator calculator) {
+ @Override
+ public Object getCalculatedValue(final int columnPosition, final int rowPosition,
+ boolean calculateInBackground, final ICalculator calculator) {
ICalculatedValueCacheKey key = null;
if (this.useColumnAsKey && this.useRowAsKey) {
@@ -204,35 +174,9 @@
calculateInBackground, calculator);
}
- /**
- * Returns the calculated value for the specified column and row position.
- * If there is no calculated value for that coordinates in the cache or
- * there is a potentially stale value, the re-calculation of the value is
- * executed.
- * <p>
- * This method uses the given ICalculatedValueCacheKey instead of
- * determining the cache key out of the CalculatedValueCache key
- * configuration.
- *
- * @param columnPosition
- * The column position of the requested value.
- * @param rowPosition
- * The row position of the requested value.
- * @param key
- * The key that is used by this CalculatedValueCache.
- * @param calculateInBackground
- * Flag to specify whether the value calculation should be
- * processed in the background or not. Setting this value to
- * <code>false</code> will cause calculation in the UI thread,
- * which is usually necessary in case of exporting and printing.
- * @param calculator
- * The {@link ICalculator} that is used for calculating the
- * values.
- * @return The value for the given coordinates.
- */
- public Object getCalculatedValue(final int columnPosition,
- final int rowPosition, final ICalculatedValueCacheKey key,
- boolean calculateInBackground, final ICalculator calculator) {
+ @Override
+ public Object getCalculatedValue(final int columnPosition, final int rowPosition,
+ final ICalculatedValueCacheKey key, boolean calculateInBackground, final ICalculator calculator) {
Object result = null;
@@ -243,14 +187,12 @@
result = cacheCopyValue;
// if the calculated value is not the same as the cache value, we
- // need to
- // start the calculation process
+ // need to start the calculation process
if (cacheCopyValue == null
|| !cacheValuesEqual(cacheValue, cacheCopyValue)) {
// if this CalculatedValueCache is not configured for smooth
- // updates, return null
- // instead of the previous calculated value
+ // updates, return null instead of the previous calculated value
if (!this.smoothUpdates) {
result = null;
}
@@ -262,8 +204,7 @@
addToCache(key, summaryValue);
// only fire an update event if the new calculated value
- // is
- // different to the value in the cache copy
+ // is different to the value in the cache copy
if (!cacheValuesEqual(summaryValue, cacheCopyValue)
&& CalculatedValueCache.this.layer != null) {
CalculatedValueCache.this.layer.fireLayerEvent(new CellVisualChangeEvent(
@@ -284,22 +225,12 @@
return result;
}
- /**
- * Clear the internal cache. Doing this will result in triggering new
- * calculations. If the values where calculated before, using the cache copy
- * still the already calculated values will be returned until the new
- * calculation is done.
- */
+ @Override
public void clearCache() {
this.cache.clear();
}
- /**
- * Kills all cached values. The internal cache aswell as the cache copy to
- * support smooth updates of values. This is necessary because on structural
- * changes, e.g. deleting/adding rows, the cache copy would return false
- * values.
- */
+ @Override
public void killCache() {
this.cache.clear();
this.cacheCopy.clear();
@@ -324,9 +255,7 @@
}
}
- /**
- * Cleaning up internal resources like shutting down the ExecutorService.
- */
+ @Override
public void dispose() {
this.executor.shutdownNow();
}
@@ -346,17 +275,7 @@
&& value2 != null && value1.equals(value2)));
}
- /**
- * Set the layer that should be used by this CalculatedValueCache to trigger
- * updates after the calculation processing is done. Necessary if the
- * caching is connected to a data provider for example, which is not able to
- * fire events itself.
- *
- * @param layer
- * The ILayer that should be used to fire the
- * CellVisualChangeEvent after the background calculation process
- * is done.
- */
+ @Override
public void setLayer(ILayer layer) {
this.layer = layer;
}
@@ -364,8 +283,6 @@
/**
* ICalculatedValueCacheKey that uses either the column or row position as
* key.
- *
- * @author Dirk Fauth
*/
class PositionValueCacheKey implements ICalculatedValueCacheKey {
@@ -407,8 +324,6 @@
/**
* ICalculatedValueCacheKey that uses the column and row position as key.
- *
- * @author Dirk Fauth
*/
class CoordinateValueCacheKey implements ICalculatedValueCacheKey {
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/util/ICalculatedValueCache.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/util/ICalculatedValueCache.java
new file mode 100644
index 0000000..30d8d4c
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/util/ICalculatedValueCache.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Dirk Fauth and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.util;
+
+import org.eclipse.nebula.widgets.nattable.layer.ILayer;
+
+/**
+ * Interface for specifying a value cache to support value calculations in a
+ * background thread.
+ *
+ * @see CalculatedValueCache
+ */
+public interface ICalculatedValueCache {
+
+ /**
+ * Returns the calculated value for the specified column and row position.
+ * If there is no calculated value for that coordinates in the cache or
+ * there is a potentially stale value, the re-calculation of the value is
+ * executed.
+ * <p>
+ * This method tries to use a predefined cache key dependent on the
+ * configuration of this CalculatedValueCache.
+ *
+ * @param columnPosition
+ * The column position of the requested value.
+ * @param rowPosition
+ * The row position of the requested value.
+ * @param calculateInBackground
+ * Flag to specify whether the value calculation should be
+ * processed in the background or not. Setting this value to
+ * <code>false</code> will cause calculation in the UI thread,
+ * which is usually necessary in case of exporting and printing.
+ * @param calculator
+ * The {@link ICalculator} that is used for calculating the
+ * values.
+ * @return The value for the given coordinates.
+ *
+ * @throws IllegalStateException
+ * if this CalculatedValueCache is configured to not use the
+ * column and row position for cache key definition.
+ */
+ public abstract Object getCalculatedValue(int columnPosition,
+ int rowPosition, boolean calculateInBackground,
+ ICalculator calculator);
+
+ /**
+ * Returns the calculated value for the specified column and row position.
+ * If there is no calculated value for that coordinates in the cache or
+ * there is a potentially stale value, the re-calculation of the value is
+ * executed.
+ * <p>
+ * This method uses the given ICalculatedValueCacheKey instead of
+ * determining the cache key out of the CalculatedValueCache key
+ * configuration.
+ *
+ * @param columnPosition
+ * The column position of the requested value.
+ * @param rowPosition
+ * The row position of the requested value.
+ * @param key
+ * The key that is used by this CalculatedValueCache.
+ * @param calculateInBackground
+ * Flag to specify whether the value calculation should be
+ * processed in the background or not. Setting this value to
+ * <code>false</code> will cause calculation in the UI thread,
+ * which is usually necessary in case of exporting and printing.
+ * @param calculator
+ * The {@link ICalculator} that is used for calculating the
+ * values.
+ * @return The value for the given coordinates.
+ */
+ public abstract Object getCalculatedValue(int columnPosition,
+ int rowPosition, ICalculatedValueCacheKey key,
+ boolean calculateInBackground, ICalculator calculator);
+
+ /**
+ * Clear the internal cache. Doing this will result in triggering new
+ * calculations. If the values where calculated before, using the cache copy
+ * still the already calculated values will be returned until the new
+ * calculation is done.
+ */
+ public abstract void clearCache();
+
+ /**
+ * Kills all cached values. The internal cache aswell as the cache copy to
+ * support smooth updates of values. This is necessary because on structural
+ * changes, e.g. deleting/adding rows, the cache copy would return false
+ * values.
+ */
+ public abstract void killCache();
+
+ /**
+ * Cleaning up internal resources like shutting down the ExecutorService.
+ */
+ public abstract void dispose();
+
+ /**
+ * Set the layer that should be used by this CalculatedValueCache to trigger
+ * updates after the calculation processing is done. Necessary if the
+ * caching is connected to a data provider for example, which is not able to
+ * fire events itself.
+ *
+ * @param layer
+ * The ILayer that should be used to fire the
+ * CellVisualChangeEvent after the background calculation process
+ * is done.
+ */
+ public abstract void setLayer(ILayer layer);
+
+}
\ No newline at end of file
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_800_Integration/_803_CachedCalculatingGridExample.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_800_Integration/_803_CachedCalculatingGridExample.java
index bc1f30b..a9a7cd4 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_800_Integration/_803_CachedCalculatingGridExample.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_800_Integration/_803_CachedCalculatingGridExample.java
@@ -63,6 +63,7 @@
import org.eclipse.nebula.widgets.nattable.summaryrow.SummationSummaryProvider;
import org.eclipse.nebula.widgets.nattable.util.CalculatedValueCache;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
+import org.eclipse.nebula.widgets.nattable.util.ICalculatedValueCache;
import org.eclipse.nebula.widgets.nattable.util.ICalculator;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.SWT;
@@ -288,7 +289,7 @@
class CachedValueCalculatingDataProvider<T> extends
GlazedListsDataProvider<T> {
- private CalculatedValueCache valueCache;
+ private ICalculatedValueCache valueCache;
public CachedValueCalculatingDataProvider(EventList<T> list,
IColumnAccessor<T> columnAccessor) {
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayer.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayer.java
index a15f181..a70c978 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayer.java
@@ -10,6 +10,7 @@
* Roman Flueckiger <roman.flueckiger@mac.com> - Bug 454566
* Dirk Fauth <dirk.fauth@googlemail.com> - Bug 448115, 449361, 453874
* Dirk Fauth <dirk.fauth@googlemail.com> - Bug 444839, 444855, 453885
+ * Dirk Fauth <dirk.fauth@googlemail.com> - Bug 459246
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
@@ -44,6 +45,7 @@
import org.eclipse.nebula.widgets.nattable.summaryrow.command.CalculateSummaryRowValuesCommand;
import org.eclipse.nebula.widgets.nattable.tree.TreeLayer;
import org.eclipse.nebula.widgets.nattable.util.CalculatedValueCache;
+import org.eclipse.nebula.widgets.nattable.util.ICalculatedValueCache;
import org.eclipse.nebula.widgets.nattable.util.ICalculatedValueCacheKey;
import org.eclipse.nebula.widgets.nattable.util.ICalculator;
import org.eclipse.swt.custom.BusyIndicator;
@@ -106,7 +108,7 @@
* The value cache that contains the summary values and performs summary
* calculation in background processes if necessary.
*/
- private CalculatedValueCache valueCache;
+ private ICalculatedValueCache valueCache;
/** Map the group to a dynamic list of group elements */
private final Map<GroupByObject, FilterList<T>> filtersByGroup = new ConcurrentHashMap<GroupByObject, FilterList<T>>();
@@ -503,6 +505,34 @@
}
/**
+ * @return The {@link ICalculatedValueCache} that contains the summary
+ * values and performs summary calculation in background processes
+ * if necessary.
+ */
+ public ICalculatedValueCache getValueCache() {
+ return this.valueCache;
+ }
+
+ /**
+ * Set the {@link ICalculatedValueCache} that should be used internally to
+ * calculate the summary values in a background thread and cache the
+ * results.
+ * <p>
+ * <b><u>Note:</u></b> By default the {@link CalculatedValueCache} is used.
+ * Be sure you know what you are doing when you are trying to exchange the
+ * implementation.
+ * </p>
+ *
+ * @param valueCache
+ * The {@link ICalculatedValueCache} that contains the summary
+ * values and performs summary calculation in background
+ * processes if necessary.
+ */
+ public void setValueCache(ICalculatedValueCache valueCache) {
+ this.valueCache = valueCache;
+ }
+
+ /**
* Simple {@link ExpansionModel} that shows every node expanded initially.
* <p>
* It is not strictly necessary for implementors to record the