Skip to content

Commit

Permalink
UI performance: navigator event model refactoring
Browse files Browse the repository at this point in the history
Former-commit-id: aa6cdef
  • Loading branch information
serge-rider committed Sep 26, 2017
1 parent c9d1938 commit dbe4097
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 110 deletions.
Expand Up @@ -455,4 +455,9 @@ public void run() {
});
}
}

@Override
public void executeInUI(Runnable runnable) {
syncExec(runnable);
}
}
Expand Up @@ -303,12 +303,7 @@ public void nodeChanged(final DBNEvent event)
// Add or remove - just reload list content
loadData(false);
} else {
DBeaverUI.asyncExec(new Runnable() {
@Override
public void run() {
getItemsViewer().update(event.getNode(), null);
}
});
getItemsViewer().update(event.getNode(), null);
}
}
}
Expand Down
Expand Up @@ -78,16 +78,10 @@ public void nodeChanged(final DBNEvent event)
event.getNodeChange() == DBNEvent.NodeChange.LOAD)
{
if (getTreeNode() == event.getNode()) {
runner = new Runnable() {
@Override
public void run()
{
databaseEditor.refreshPart(
event,
event.getNodeChange() == DBNEvent.NodeChange.REFRESH &&
event.getSource() == DBNEvent.FORCE_REFRESH);
}
};
databaseEditor.refreshPart(
event,
event.getNodeChange() == DBNEvent.NodeChange.REFRESH &&
event.getSource() == DBNEvent.FORCE_REFRESH);
}
} else if (event.getNodeChange() == DBNEvent.NodeChange.UNLOAD) {
closeEditor = true;
Expand All @@ -99,16 +93,10 @@ public void run()
dispose();
return;
}
runner = new Runnable() { @Override
public void run() {
IWorkbenchPage workbenchPage = databaseEditor.getSite().getWorkbenchWindow().getActivePage();
if (workbenchPage != null) {
workbenchPage.closeEditor(databaseEditor, false);
}
}};
}
if (runner != null) {
DBeaverUI.asyncExec(runner);
IWorkbenchPage workbenchPage = databaseEditor.getSite().getWorkbenchWindow().getActivePage();
if (workbenchPage != null) {
workbenchPage.closeEditor(databaseEditor, false);
}
}
}
}
Expand Down
Expand Up @@ -190,25 +190,43 @@ public void nodeChanged(final DBNEvent event)
final DBNNode node = event.getNode();
final DBNNode parentNode = node.getParentNode();
if (parentNode != null) {
DBeaverUI.syncExec(new Runnable() {
@Override
public void run() {
if (!treeViewer.getControl().isDisposed()) {
if (!parentNode.isDisposed()) {
treeViewer.refresh(getViewerObject(parentNode));
if (event.getNodeChange() == DBNEvent.NodeChange.SELECT) {
treeViewer.reveal(node);
treeViewer.setSelection(new StructuredSelection(node));
}
}
if (!treeViewer.getControl().isDisposed()) {
if (!parentNode.isDisposed()) {
treeViewer.refresh(getViewerObject(parentNode));
if (event.getNodeChange() == DBNEvent.NodeChange.SELECT) {
treeViewer.reveal(node);
treeViewer.setSelection(new StructuredSelection(node));
}
}
});
}
}
break;
}
case UPDATE:
DBeaverUI.syncExec(new NodeUpdater(event));
if (!treeViewer.getControl().isDisposed() && !treeViewer.isBusy()) {
if (event.getNode() != null) {
switch (event.getNodeChange()) {
case LOAD:
treeViewer.refresh(getViewerObject(event.getNode()));
expandNodeOnLoad(event.getNode());
break;
case UNLOAD:
treeViewer.collapseToLevel(event.getNode(), -1);
treeViewer.refresh(getViewerObject(event.getNode()));
break;
case REFRESH:
treeViewer.refresh(getViewerObject(event.getNode()), true);
break;
case LOCK:
case UNLOCK:
case STRUCT_REFRESH:
treeViewer.refresh(getViewerObject(event.getNode()));
break;
}
} else {
log.warn("Null node object");
}
}
break;
default:
break;
Expand Down Expand Up @@ -506,37 +524,4 @@ public IStatus runInUIThread(IProgressMonitor monitor) {
}
}

private class NodeUpdater implements Runnable {
private final DBNEvent event;
NodeUpdater(DBNEvent event) {
this.event = event;
}
@Override
public void run() {
if (!treeViewer.getControl().isDisposed() && !treeViewer.isBusy()) {
if (event.getNode() != null) {
switch (event.getNodeChange()) {
case LOAD:
treeViewer.refresh(getViewerObject(event.getNode()));
expandNodeOnLoad(event.getNode());
break;
case UNLOAD:
treeViewer.collapseToLevel(event.getNode(), -1);
treeViewer.refresh(getViewerObject(event.getNode()));
break;
case REFRESH:
treeViewer.refresh(getViewerObject(event.getNode()), true);
break;
case LOCK:
case UNLOCK:
case STRUCT_REFRESH:
treeViewer.refresh(getViewerObject(event.getNode()));
break;
}
} else {
log.warn("Null node object");
}
}
}
}
}
Expand Up @@ -847,19 +847,14 @@ public void nodeChanged(DBNEvent event) {
}
final DBNNode node = event.getNode();
if (node instanceof DBNResource && activeFile.equals(((DBNResource) node).getResource())) {
DBeaverUI.syncExec(new Runnable() {
@Override
public void run() {
final int selConnection = connectionCombo.getSelectionIndex();
if (selConnection > 0 && activeFile != null) {
DBPDataSourceContainer visibleContainer = connectionCombo.getItem(selConnection);
DBPDataSourceContainer newContainer = EditorUtils.getFileDataSource(activeFile);
if (newContainer != visibleContainer) {
updateControls(true);
}
}
final int selConnection = connectionCombo.getSelectionIndex();
if (selConnection > 0 && activeFile != null) {
DBPDataSourceContainer visibleContainer = connectionCombo.getItem(selConnection);
DBPDataSourceContainer newContainer = EditorUtils.getFileDataSource(activeFile);
if (newContainer != visibleContainer) {
updateControls(true);
}
});
}
}
}

Expand Down
Expand Up @@ -18,11 +18,8 @@

import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.ext.generic.model.GenericStructContainer;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource;
import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCBasicDataTypeCache;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSDataType;

import java.util.ArrayList;
import java.util.List;
Expand Down
Expand Up @@ -26,13 +26,15 @@
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBIconComposite;
import org.jkiss.dbeaver.model.app.DBPPlatform;
import org.jkiss.dbeaver.model.DBPImage;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.app.DBPPlatform;
import org.jkiss.dbeaver.model.navigator.meta.DBXTreeFolder;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.model.struct.DBSObjectState;
import org.jkiss.dbeaver.runtime.ui.DBUserInterface;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;

Expand Down Expand Up @@ -71,6 +73,7 @@ public String first() {
private DBNRoot root;
private final List<INavigatorListener> listeners = new ArrayList<>();
private transient INavigatorListener[] listenersCopy = null;
private final transient List<DBNEvent> eventCache = new ArrayList<>();
private final Map<DBSObject, Object> nodeMap = new HashMap<>();

public DBNModel(DBPPlatform platform) {
Expand All @@ -94,6 +97,8 @@ public void initialize()
}

platform.getWorkspace().addResourceChangeListener(this);

new EventProcessingJob().schedule();
}

public void dispose()
Expand Down Expand Up @@ -511,29 +516,9 @@ void fireNodeEvent(final DBNEvent event)
if (platform.isShuttingDown()) {
return;
}
final INavigatorListener[] listenersCopy;
synchronized (this.listeners) {
if (listeners.isEmpty()) {
return;
}
listenersCopy = this.listenersCopy;
}
if (listenersCopy.length == 0) {
return;
synchronized (eventCache) {
eventCache.add(event);
}
// Notify listeners in detached job
new Job("Notify node '" + event.getNode().getName() + "' changes") {
{
setSystem(true);
}
@Override
protected IStatus run(IProgressMonitor monitor) {
for (INavigatorListener listener : listenersCopy) {
listener.nodeChanged(event);
}
return Status.OK_STATUS;
}
}.schedule();
}

@Override
Expand Down Expand Up @@ -620,4 +605,51 @@ public void ensureProjectLoaded(IProject project) {
projectNode.getDatabases();
}
}

private class EventProcessingJob extends Job {

EventProcessingJob() {
super("Navigator notifier");
setSystem(true);
}

@Override
protected IStatus run(IProgressMonitor monitor) {
while (!platform.isShuttingDown()) {
RuntimeUtils.pause(100);
final INavigatorListener[] realListeners;
synchronized (listeners) {
realListeners = listenersCopy;
}
if (realListeners == null || realListeners.length == 0) {
continue;
}
DBNEvent[] realEvents;
synchronized (eventCache) {
if (eventCache.isEmpty()) {
continue;
}
realEvents = eventCache.toArray(new DBNEvent[eventCache.size()]);
eventCache.clear();
}

try {
DBUserInterface.getInstance().executeInUI(new Runnable() {
@Override
public void run() {
for (int i = 0; i < realEvents.length; i++) {
for (INavigatorListener listener : listenersCopy) {
listener.nodeChanged(realEvents[i]);
}
}
}
});
} catch (Exception e) {
log.error(e);
}
}
return Status.OK_STATUS;
}
}

}
Expand Up @@ -22,5 +22,8 @@
*/
public interface INavigatorListener
{
/**
* Called in UI thread
*/
void nodeChanged(DBNEvent event);
}
Expand Up @@ -44,4 +44,6 @@ enum UserResponse {

void executeProcess(DBRProcessDescriptor processDescriptor);

void executeInUI(Runnable runnable);

}
Expand Up @@ -74,6 +74,11 @@ public void executeProcess(DBRProcessDescriptor processDescriptor) {
DBUserInterface.getInstance().showError("Execute process", processDescriptor.getName(), e);
}
}

@Override
public void executeInUI(Runnable runnable) {
runnable.run();
}
};

public static DBPPlatformUI getInstance() {
Expand Down

0 comments on commit dbe4097

Please sign in to comment.