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 247146 - Inefficient removing all nodes from Children.Array
Summary: Inefficient removing all nodes from Children.Array
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Nodes (show other bugs)
Version: 8.0
Hardware: PC Solaris
: P3 normal (vote)
Assignee: Alexander Simon
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-09-16 06:29 UTC by Alexander Simon
Modified: 2015-03-06 04:11 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
proposed patch (1.80 KB, patch)
2014-09-16 06:36 UTC, Alexander Simon
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Simon 2014-09-16 06:29:58 UTC
Method Children.Array.remove(children.getNodes()) has O(N*N) complexity.
It can result in UI freeze.
Example:
- Create C/C++ application
- open main.cpp file
- replace content with content:
--------------------8<-----------------
#define DEFINE_STRUCT(index) struct Num##index {int foo##index();};

#define GEN_STRUCT_0(index) DEFINE_STRUCT(index##1) 
#define GEN_STRUCT_1(index) GEN_STRUCT_0(index##1) GEN_STRUCT_0(index##2)  GEN_STRUCT_0(index##3) GEN_STRUCT_0(index##4) 
#define GEN_STRUCT_2(index) GEN_STRUCT_1(index##1) GEN_STRUCT_1(index##2)  GEN_STRUCT_1(index##3) GEN_STRUCT_1(index##4) 
#define GEN_STRUCT_3(index) GEN_STRUCT_2(index##1) GEN_STRUCT_2(index##2)  GEN_STRUCT_2(index##3) GEN_STRUCT_2(index##4) 
#define GEN_STRUCT_4(index) GEN_STRUCT_3(index##1) GEN_STRUCT_3(index##2)  GEN_STRUCT_3(index##3) GEN_STRUCT_3(index##4) 
#define GEN_STRUCT_5(index) GEN_STRUCT_4(index##1) GEN_STRUCT_4(index##2)  GEN_STRUCT_4(index##3) GEN_STRUCT_4(index##4) 
#define GEN_STRUCT_6(index) GEN_STRUCT_5(index##1) GEN_STRUCT_5(index##2)  GEN_STRUCT_5(index##3) GEN_STRUCT_5(index##4) 
#define GEN_STRUCT_7(index) GEN_STRUCT_6(index##1) GEN_STRUCT_6(index##2)  GEN_STRUCT_6(index##3) GEN_STRUCT_6(index##4) 
#define GEN_STRUCT_8(index) GEN_STRUCT_7(index##1) GEN_STRUCT_7(index##2)  GEN_STRUCT_7(index##3) GEN_STRUCT_7(index##4) 
#define GEN_STRUCT_9(index) GEN_STRUCT_8(index##1) GEN_STRUCT_8(index##2)  GEN_STRUCT_8(index##3) GEN_STRUCT_8(index##4) 
#define GEN_STRUCT_10(index) GEN_STRUCT_9(index##1) GEN_STRUCT_9(index##2)  GEN_STRUCT_9(index##3) GEN_STRUCT_9(index##4) 
#define GEN_STRUCT_11(index) GEN_STRUCT_10(index##1) GEN_STRUCT_10(index##2)  GEN_STRUCT_10(index##3) GEN_STRUCT_10(index##4) 

GEN_STRUCT_9(0) 
--------------------8<-----------------
- wait when navigator content is shown
- replace "GEN_STRUCT_9(0)" to "GEN_STRUCT_5(0)" and save file
Result
- UI freeze.

Stack is:
"Editor Parsing Loop (20140916-fd6a6de7be2b)" #75 daemon prio=1 os_prio=64 tid=0x00000000027bb800 nid=0x4b runnable [0xffff80ff8ebfe000]
   java.lang.Thread.State: RUNNABLE
	at java.util.Arrays$ArrayList.indexOf(Arrays.java:3860)
	at java.util.Arrays$ArrayList.contains(Arrays.java:3868)
	at java.util.ArrayList.batchRemove(ArrayList.java:720)
	at java.util.ArrayList.removeAll(ArrayList.java:690)
	at org.openide.nodes.Children$Array.remove(Children.java:835)
	- locked <0x00000006c0f705a0> (a java.lang.Object)
	at org.netbeans.modules.cnd.qnavigator.navigator.NavigatorModel$2.run(NavigatorModel.java:154)
	at org.openide.util.Mutex.writeAccess(Mutex.java:479)
	at org.openide.util.Mutex$1R.run(Mutex.java:1328)
	at org.openide.nodes.Children$ProjectManagerDeadlockDetector.execute(Children.java:1921)
	at org.openide.util.Mutex.doWrapperAccess(Mutex.java:1341)
	at org.openide.util.Mutex.writeAccess(Mutex.java:468)
	at org.netbeans.modules.cnd.qnavigator.navigator.NavigatorModel.setChildren(NavigatorModel.java:150)
	at org.netbeans.modules.cnd.qnavigator.navigator.NavigatorModel.update(NavigatorModel.java:184)
	- locked <0x00000006c2d4e960> (a org.netbeans.modules.cnd.qnavigator.navigator.NavigatorModel$Lock)
	at org.netbeans.modules.cnd.qnavigator.navigator.NavigatorNodeFactoryTask.run(NavigatorNodeFactoryTask.java:138)
	at org.netbeans.modules.parsing.impl.TaskProcessor.callParserResultTask(TaskProcessor.java:573)
	at org.netbeans.modules.parsing.impl.TaskProcessor$CompilationJob.run(TaskProcessor.java:744)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1423)
	at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2033)
Comment 1 Alexander Simon 2014-09-16 06:36:10 UTC
Created attachment 149238 [details]
proposed patch
Comment 2 Vladimir Voskresensky 2014-09-16 13:17:15 UTC
some notes:
the UI freeze is caused by EDT requiring Mutex while client's are doing 
children.remove(children.getNodes())

We should either introduce children.clear() to have O(1) or temporary accept proposed patch to have 0(n) for such cases
Comment 3 Ondrej Vrabec 2015-03-04 13:51:16 UTC
i think you may go ahead and apply the patch.
Comment 4 Alexander Simon 2015-03-04 18:48:55 UTC
fixed, change set:
http://hg.netbeans.org/cnd-main/rev/7f27dde452cd
Comment 5 Quality Engineering 2015-03-06 04:11:36 UTC
Integrated into 'main-silver', will be available in build *201503060001* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)

Changeset: http://hg.netbeans.org/main-silver/rev/7f27dde452cd
User: Alexander Simon <alexvsimon@netbeans.org>
Log: fixed Bug #247146 Inefficient removing all nodes from Children.Array