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 20036

Summary: Improve efficiency and correctness of LookupManager
Product: xml Reporter: Jesse Glick <jglick>
Component: CodeAssignee: _ pkuzel <pkuzel>
Status: CLOSED FIXED    
Severity: blocker Keywords: PERFORMANCE
Priority: P1    
Version: 3.x   
Hardware: PC   
OS: Linux   
Issue Type: TASK Exception Reporter:
Attachments: Suggested patch

Description Jesse Glick 2002-02-01 11:55:21 UTC
While working on #14722, I found that firing a lookup change at a certain time
during startup (while opening the project) caused a long (30-sec) infinite loop
and huge performance problems. These went away if the XML Core module was
uninstalled. According to OptimizeIt!, LookupManager.updateResult was being
called many times in a row, for no apparent reason, and each time it would
itself trigger a cookie change in the processor for Entity Catalog XML files
(used by web/core only), which in turn caused lookup to change again and create
a feedback loop.

Looking at LookupManager, I see two problems, both corrected by this patch
(which restores normal behavior as far as I can tell):

1. It used the boolean value of Collection.removeAll(Collection) as a test for
whether or not to fire changes. I think the logic is just wrong - the return
value here means "did the collection change as a result?". You want to ask (I
think) "is the collection now non-empty?". For example:

        Collection currentResult = getLookupResult().allInstances();
        Collection lastResultCopy = new ArrayList (lastResult);
        Collection currentResultCopy = new ArrayList (currentResult);
        
        if ( lastResultCopy.removeAll (currentResult) ) {
            removedFromResult (lastResultCopy);
        // ...

Say the actual result never changes (though LookupListener keeps firing). Each
time, currentResult.equals(lastResult); this means
lastResultCopy.removeAll(currentResult) is true, so the method is called. The
patch just calculates what items were added or removed, and calls the method if
there were any, which I think is what was intended.

2. Every XMLDataObject in the system - and there are a lot - had its own
LookupManager (CookieManager) instance; each one individually kept its own
lookup result and listener. This is very wasteful. In fact it seems only two
classes are ever searched on. The patch causes all LookupManager's searching for
the same class to share a result and listener (inner class Handle).

Minor changes to CookieManager were necessary too. Registration of the listener
can be done from within the constructor, but must come after any needed
initialization, or there could be timing problems.
Comment 1 Jesse Glick 2002-02-01 11:55:44 UTC
Created attachment 4519 [details]
Suggested patch
Comment 2 _ lkramolis 2002-02-08 08:48:37 UTC
Applied.
Comment 3 dmladek 2004-08-20 17:17:17 UTC
I guest it's properly done :-) ...closing it