This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 48887 - redundant TreeModel listener registrations
Summary: redundant TreeModel listener registrations
Status: CLOSED FIXED
Alias: None
Product: debugger
Classification: Unclassified
Component: Code (show other bugs)
Version: 4.x
Hardware: All All
: P3 blocker (vote)
Assignee: issues@debugger
URL:
Keywords: API, PERFORMANCE
Depends on:
Blocks:
 
Reported: 2004-09-11 21:11 UTC by ivan
Modified: 2010-04-29 09:19 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ivan 2004-09-11 21:11:11 UTC
The TreeModel listener registration could be improved.

The modelview pkg divides the model into four
interfaces, TreeModel,
NodeModel, NodeActionsProvider and TableModel.
Each interface
dictates that TreeModelListener listeners be
registered.

The client can utilize these interfacse in one of
two ways.
a) create subclasses for each interface (all four
or only the ones they need)
b) create one subclass that implemets all interfaces.

The TreeModelListener registration is driven from
within debuggercore via
CompountModel.addTreeModelListener():

    public void addTreeModelListener
(TreeModelListener l) {
        treeModel.addTreeModelListener (l);
        if (nodeModel != null)
            nodeModel.addTreeModelListener (l);
        if (nodeActionsProvider != null)
           
nodeActionsProvider.addTreeModelListener (l);
        if (tableModel != null)
            tableModel.addTreeModelListener (l);
    }

This implementation is sub-par from a performance
POV for both use cases.

In case (a) the same listener is recorded for four
distinct sub-model
implementations. This doesn't make sense since one
would expect that
the listener for the treemodel be a callback that
affects only
tree-like properties, and that the listener for
the actions provider
be one that affects only the actions. But from the
above code it seems
that one callback is used for everything. The
result is that the
hapless client will call the listener from each
sub-model and the same
callback will be called redundantly.

In case (b) there is one model implementation but
the same listener
gets registered with it, redundantly, four times.
So whenever my model
changes I end up calling tree[Node]Changed() four
times which cause
countless pulls from the model and who knows how
many view refreshes.
(Not to mention that debugging becomes very tedious).

-----------------------------------------------------------------

A natural solution to the (a) scenario is to have
4 distinct callbacks
and listeners.

A solution to (b) that comes to mind is as
following, although
it's hard to see how it could be extended to deal
with (a) efficiently.

    public void addTreeModelListener
(TreeModelListener l) {
        treeModel.addTreeModelListener (l);

        if (nodeModel != null && (nodeModel !=
treeModel))
            nodeModel.addTreeModelListener (l);

        if (nodeActionsProvider != null &&
(nodeActionsProvider != nodeModel &&
                                           
nodeActionsProvider != treeModel))
           
nodeActionsProvider.addTreeModelListener (l);

        if (tableModel != null && (tableModel !=
nodeActionsProvider) &&
                                   tableModel !=
nodeModel &&
                                   tableModel !=
treeModel))
            tableModel.addTreeModelListener (l);
    }
~
~
Comment 1 Jan Jancura 2004-10-27 13:54:33 UTC
This issue should be disscussed more.
Probably no influence on Java Debugger.
Comment 2 Martin Entlicher 2005-05-31 14:46:10 UTC
This affects performance and should be addressed in 4.2.
Comment 3 Martin Entlicher 2005-08-16 15:08:23 UTC
This is in fact already solved. The redundant firing caused already problems to
me, therefore this is already fixed for some time...

a)
        public void addModelListener (ModelListener l) {
            treeModel.addModelListener (l);
            if (nodeModel != treeModel) {
                nodeModel.addModelListener (l);
            }
            if (tableModel != treeModel && tableModel != nodeModel) {
                tableModel.addModelListener (l);
            }
        }

b)
There are specific events that should be fired when the given change happens.
See e.g. the change masks in ModelEvent.NodeChanged.
Comment 4 Quality Engineering 2010-04-29 09:19:15 UTC
Verified ... and Closing all issues resolved into NetBeans 6.7 and earlier.