summaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/data/RpcDataProviderExtension.java
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2015-02-10 10:13:08 +0200
committerVaadin Code Review <review@vaadin.com>2015-03-16 13:02:07 +0000
commite80f04ade51456e175e9fa7d6f8019f41fa730de (patch)
tree3e90926ca8e685a5cd37fdb159881d8fca38f33d /server/src/com/vaadin/data/RpcDataProviderExtension.java
parenta4b6c9fe370f2997e24413a0db8de014105eb02a (diff)
downloadvaadin-framework-e80f04ade51456e175e9fa7d6f8019f41fa730de.tar.gz
vaadin-framework-e80f04ade51456e175e9fa7d6f8019f41fa730de.zip
Optimise RpcDataProvider calls to container (#16642)
Change-Id: I8abaa4c1bd8eface98e42e0882cf09c92fbbf386
Diffstat (limited to 'server/src/com/vaadin/data/RpcDataProviderExtension.java')
-rw-r--r--server/src/com/vaadin/data/RpcDataProviderExtension.java119
1 files changed, 37 insertions, 82 deletions
diff --git a/server/src/com/vaadin/data/RpcDataProviderExtension.java b/server/src/com/vaadin/data/RpcDataProviderExtension.java
index 991cb0537d..5fb0742164 100644
--- a/server/src/com/vaadin/data/RpcDataProviderExtension.java
+++ b/server/src/com/vaadin/data/RpcDataProviderExtension.java
@@ -85,77 +85,36 @@ public class RpcDataProviderExtension extends AbstractExtension {
* doesn't leak memory.
*/
public class DataProviderKeyMapper implements Serializable {
- private final BiMap<Integer, Object> indexToItemId = HashBiMap.create();
private final BiMap<Object, String> itemIdToKey = HashBiMap.create();
private Set<Object> pinnedItemIds = new HashSet<Object>();
- private Range activeRange = Range.withLength(0, 0);
private long rollingIndex = 0;
private DataProviderKeyMapper() {
// private implementation
}
- void setActiveRange(Range newActiveRange) {
- final Range[] removed = activeRange.partitionWith(newActiveRange);
- final Range[] added = newActiveRange.partitionWith(activeRange);
-
- removeActiveRows(removed[0]);
- removeActiveRows(removed[2]);
- addActiveRows(added[0]);
- addActiveRows(added[2]);
-
- activeRange = newActiveRange;
- }
-
- private void removeActiveRows(final Range deprecated) {
- for (int i = deprecated.getStart(); i < deprecated.getEnd(); i++) {
- final Integer ii = Integer.valueOf(i);
- final Object itemId = indexToItemId.get(ii);
-
- if (!isPinned(itemId)) {
- itemIdToKey.remove(itemId);
- indexToItemId.remove(ii);
+ /**
+ * Sets the currently active rows. This will purge any unpinned rows
+ * from cache.
+ *
+ * @param itemIds
+ * collection of itemIds to map to row keys
+ */
+ void setActiveRows(Collection<?> itemIds) {
+ Set<Object> itemSet = new HashSet<Object>(itemIds);
+ Set<Object> itemsRemoved = new HashSet<Object>();
+ for (Object itemId : itemIdToKey.keySet()) {
+ if (!itemSet.contains(itemId) && !isPinned(itemId)) {
+ itemsRemoved.add(itemId);
}
}
- }
- private void addActiveRows(Range added) {
- if (added.isEmpty()) {
- // Some container.getItemIds() implementations just might be
- // expensive even for an empty range, so bail out early
- return;
+ for (Object itemId : itemsRemoved) {
+ itemIdToKey.remove(itemId);
}
- List<?> newItemIds = container.getItemIds(added.getStart(),
- added.length());
- Integer index = added.getStart();
- for (Object itemId : newItemIds) {
- /*
- * We might be in a situation we have an index <-> itemId entry
- * already. This happens when something was selected, scrolled
- * out of view and now we're scrolling it back into view. It's
- * unnecessary to overwrite it in that case.
- *
- * Fun thought: considering branch prediction, it _might_ even
- * be a bit faster to simply always run the code inside this
- * if-state. But it sounds too stupid (and most often too
- * insignificant) to try out.
- */
- if (!indexToItemId.containsKey(index)) {
- /*
- * We might be in a situation where we have an itemId <->
- * key entry already, but no index for it. This happens when
- * something that is out of view is selected
- * programmatically. In that case, we only want to add an
- * index for that entry, and not overwrite the key.
- */
- if (!itemIdToKey.containsKey(itemId)) {
- itemIdToKey.put(itemId, nextKey());
- }
-
- indexToItemId.forcePut(index, itemId);
- }
- index++;
+ for (Object itemId : itemSet) {
+ itemIdToKey.put(itemId, getKey(itemId));
}
}
@@ -286,11 +245,6 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
pinnedItemIds.remove(itemId);
- final Integer index = indexToItemId.inverse().get(itemId);
- if (index == null || !activeRange.contains(index.intValue())) {
- itemIdToKey.remove(itemId);
- indexToItemId.remove(index);
- }
}
/**
@@ -303,10 +257,6 @@ public class RpcDataProviderExtension extends AbstractExtension {
public boolean isPinned(Object itemId) {
return pinnedItemIds.contains(itemId);
}
-
- Object itemIdAtIndex(int index) {
- return indexToItemId.get(Integer.valueOf(index));
- }
}
/**
@@ -352,10 +302,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
* @param activeRowCount
* the number of active rows
*/
- public void setActiveRows(int firstActiveRow, int activeRowCount) {
-
- final Range newActiveRange = Range.withLength(firstActiveRow,
- activeRowCount);
+ public void setActiveRows(Range newActiveRange) {
// TODO [[Components]] attach and detach components
@@ -695,8 +642,6 @@ public class RpcDataProviderExtension extends AbstractExtension {
listeners.clear();
activeRowHandler.activeRange = Range.withLength(0, 0);
- keyMapper.setActiveRange(Range.withLength(0, 0));
- keyMapper.indexToItemId.clear();
/* Mark as dirty to push changes in beforeClientResponse */
bareItemSetTriggeredSizeChange = true;
@@ -819,22 +764,32 @@ public class RpcDataProviderExtension extends AbstractExtension {
private void pushRowData(int firstRowToPush, int numberOfRows,
int firstCachedRowIndex, int cacheSize) {
- Range active = Range.withLength(firstRowToPush, numberOfRows);
- if (cacheSize != 0) {
- Range cached = Range.withLength(firstCachedRowIndex, cacheSize);
- active = active.combineWith(cached);
+ Range newRange = Range.withLength(firstRowToPush, numberOfRows);
+ Range cached = Range.withLength(firstCachedRowIndex, cacheSize);
+ Range fullRange = newRange;
+ if (!cached.isEmpty()) {
+ fullRange = newRange.combineWith(cached);
}
- keyMapper.setActiveRange(active);
+ List<?> itemIds = container.getItemIds(fullRange.getStart(),
+ fullRange.length());
+ keyMapper.setActiveRows(itemIds);
- List<?> itemIds = container.getItemIds(firstRowToPush, numberOfRows);
JsonArray rows = Json.createArray();
- for (int i = 0; i < itemIds.size(); ++i) {
- rows.set(i, getRowData(getGrid().getColumns(), itemIds.get(i)));
+
+ // Offset the index to match the wanted range.
+ int diff = 0;
+ if (!cached.isEmpty() && newRange.getStart() > cached.getStart()) {
+ diff = cached.length();
+ }
+
+ for (int i = 0; i < newRange.length() && i + diff < itemIds.size(); ++i) {
+ Object itemId = itemIds.get(i + diff);
+ rows.set(i, getRowData(getGrid().getColumns(), itemId));
}
rpc.setRowData(firstRowToPush, rows);
- activeRowHandler.setActiveRows(active.getStart(), active.length());
+ activeRowHandler.setActiveRows(fullRange);
}
private JsonValue getRowData(Collection<Column> columns, Object itemId) {