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

Summary: Inefficient removing all nodes from Children.Array
Product: platform Reporter: Alexander Simon <alexvsimon>
Component: NodesAssignee: Alexander Simon <alexvsimon>
Status: RESOLVED FIXED    
Severity: normal CC: vv159170
Priority: P3    
Version: 8.0   
Hardware: PC   
OS: Solaris   
Issue Type: DEFECT Exception Reporter:
Attachments: proposed patch

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