directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Emmanuel Lécharny <elecha...@gmail.com>
Subject Re: [Studio] Inneficient loop while cliking on an Entry's value in the browser
Date Tue, 21 Jul 2015 16:56:50 GMT
FTR, the listeners are registred in the
SingleTableEntryEditor.createPartControl() method :

actionGroup = new EntryEditorActionGroup( this );
  -> super( entryEditor.getMainWidget(), entryEditor.getConfiguration() );
    ->  for ( int i = 0; i < openValueEditorActionProxies.length; i++ )
        {
            openValueEditorActionProxies[i] = new
EntryEditorActionProxy( viewer, new OpenEditorAction( viewer,
valueEditorManager, valueEditors[i], this ) );
      -> EntryEditorActionProxy()
        -> BrowserActionProxy()
          ->  selectionProvider.addSelectionChangedListener( this );

We have 24 elements in the openValueEditorActionProxies array, because
we have 24 possible editors :

org.apache.directory.studio.valueeditors.InPlaceTextValueEditor@3fd21272,
org.apache.directory.studio.valueeditors.TextValueEditor@4b4bc73d,
org.apache.directory.studio.valueeditors.HexValueEditor@4cb91fa4,
org.apache.directory.studio.valueeditors.bool.InPlaceBooleanValueEditor@12aa2cca,

org.apache.directory.studio.valueeditors.image.ImageValueEditor@3dc4ed6f,
org.apache.directory.studio.valueeditors.adtime.ActiveDirectoryTimeValueEditor@2823b7c5,

org.apache.directory.studio.valueeditors.administrativerole.AdministrativeRoleValueEditor@2ce3d95a,

org.apache.directory.studio.valueeditors.objectclass.ObjectClassValueEditor@6f6c6c70,

org.apache.directory.studio.valueeditors.integer.IntegerValueEditor@75d95b67,

org.apache.directory.studio.valueeditors.dn.DnValueEditor@40f15786,
org.apache.directory.studio.valueeditors.msad.InPlaceMsAdObjectSidValueEditor@72ea6fcb,

org.apache.directory.studio.aciitemeditor.valueeditors.SubtreeValueEditor@7ee9920a,

org.apache.directory.studio.valueeditors.password.PasswordValueEditor@4154ecd3,

org.apache.directory.studio.valueeditors.uuid.InPlaceUuidValueEditor@b53ce18,

org.apache.directory.studio.valueeditors.time.GeneralizedTimeValueEditor@2a666c8e,

org.apache.directory.studio.valueeditors.address.AddressValueEditor@18adc20a,

org.apache.directory.studio.valueeditors.oid.InPlaceOidValueEditor@7e7987b8,

org.apache.directory.studio.valueeditors.msad.InPlaceMsAdObjectGuidValueEditor@6bcfb561,

org.apache.directory.studio.valueeditors.certificate.CertificateValueEditor@7254a68a,

org.apache.directory.studio.aciitemeditor.ACIItemValueEditor@49f9758,
org.apache.directory.studio.openldap.config.acl.editor.OpenLdapAclValueEditor@36e98434,

org.apache.directory.studio.valueeditors.MultivaluedValueEditor@209b4b35,
org.apache.directory.studio.valueeditors.EntryValueEditor@77acc95a,
org.apache.directory.studio.valueeditors.RenameValueEditor@ff1a5a0]

Ideally speaking, the listener to be called should be the one associated
with the selected AttributeType. An option would be to register an
encaspulating listener that filters the editor to call depending on teh
AttributeType.



Le 21/07/15 17:52, Emmanuel Lécharny a écrit :
> Hi !
>
> I'm facing a very innefficient piece of code while trying to play around
> teh OpenLDAP ACl editor. Here is what I do, and what I see.
>
> - I connect to an OpenLDAP remote server
> - I pick a MDB database entry (but that could be any entry which contain
> the olcAccess attributeType (every ObjectClass inheriting from
> olcDatabaseConfig, ie, any backend).
> - I open it, and get all the attributes and values in it
> - assuming there is at least one olcAccess instance in this entry, then
> the OpenLdapAclValueWithContext constructor is called 28 times !
>
> The reason is that we are iterating across all the TreeViexer
> selectionChangeListeners, and we have many (62... One per editor).
>
> This starts in :
>
>     protected void fireSelectionChanged(final SelectionChangedEvent event) {
>         Object[] listeners = selectionChangedListeners.getListeners();
>         for (Object listener : listeners) {
>             final ISelectionChangedListener l =
> (ISelectionChangedListener) listener;
>             SafeRunnable.run(new SafeRunnable() {
>                 @Override
>                 public void run() {
>                     l.selectionChanged(event); ---> This get called as
> many times as we have listeners
>                 }
>             });
>         }
>     }
>
> Each loop invokes the EntryEditorActionProxy.selectionChanged() method,
> then the BrowserActionProxy.updateAction(), which calls
> OpenEditorAction.isEnabled(), which calls the
> EntryEditorWidgetCellModifier.canModify() method, which tries to figure
> out what is the best editor for the selected value, and finally call the
> getRawValue() of the class used to edit the value.
>
> In my case, it ends up calling the ACL parser as many times we have
> listeners (28 times), even if the listeners are totally unrelated.
>
> Here is the stack trace :
>
> Thread [main] (Suspended (breakpoint at line 143 in
> OpenLdapAclValueEditor))   
>     OpenLdapAclValueEditor.getRawValue(IValue) line: 143   
>     EntryEditorWidgetCellModifier.canModify(Object, String) line: 79   
>     OpenEditorAction.isEnabled() line: 128   
>     EntryEditorActionProxy(BrowserActionProxy).updateAction() line: 248   
>    
> EntryEditorActionProxy(BrowserActionProxy).selectionChanged(SelectionChangedEvent)
> line: 237   
>     Viewer$2.run() line: 163   
>     SafeRunner.run(ISafeRunnable) line: 42   
>     JFaceUtil$1.run(ISafeRunnable) line: 50   
>     SafeRunnable.run(ISafeRunnable) line: 178   
>>>>> TreeViewer(Viewer).fireSelectionChanged(SelectionChangedEvent) line:
> 160<<<<---------------- Starting loop   
>     TreeViewer(StructuredViewer).updateSelection(ISelection) line: 2171   
>     TreeViewer(StructuredViewer).handleSelect(SelectionEvent) line: 1202   
>     StructuredViewer$4.widgetSelected(SelectionEvent) line: 1231   
>     OpenStrategy.fireSelectionEvent(SelectionEvent) line: 242   
>     OpenStrategy.access$4(OpenStrategy, SelectionEvent) line: 236   
>     OpenStrategy$1.handleEvent(Event) line: 408   
>     EventTable.sendEvent(Event) line: 84   
>     Display.sendEvent(EventTable, Event) line: 4199   
>     Tree(Widget).sendEvent(Event) line: 1467   
>     Tree(Widget).sendEvent(int, Event, boolean) line: 1490   
>     Tree(Widget).sendEvent(int, Event) line: 1475   
>     Tree(Widget).notifyListeners(int, Event) line: 1279   
>     Display.runDeferredEvents() line: 4042   
>     Display.applicationNextEventMatchingMask(long, long, long, long,
> long, long) line: 4996   
>     Display.applicationProc(long, long, long, long, long, long) line:
> 5378   
>     OS.objc_msgSendSuper(objc_super, long, long) line: not available
> [native method]   
>     Tree(Widget).callSuper(long, long, long) line: 221   
>     Tree(Widget).mouseDownSuper(long, long, long) line: 1101   
>     Tree.mouseDownSuper(long, long, long) line: 2064   
>     Tree(Widget).mouseDown(long, long, long) line: 1093   
>     Tree(Control).mouseDown(long, long, long) line: 2563   
>     Tree.mouseDown(long, long, long) line: 2032   
>     Display.windowProc(long, long, long) line: 5638   
>     OS.objc_msgSendSuper(objc_super, long, long) line: not available
> [native method]   
>     Shell(Widget).callSuper(long, long, long) line: 221   
>     Shell(Widget).windowSendEvent(long, long, long) line: 2105   
>     Shell.windowSendEvent(long, long, long) line: 2329   
>     Display.windowProc(long, long, long) line: 5702   
>     OS.objc_msgSendSuper(objc_super, long, long) line: not available
> [native method]   
>     Display.applicationSendEvent(long, long, long) line: 5139   
>     Display.applicationProc(long, long, long) line: 5288   
>     OS.objc_msgSend(long, long, long) line: not available [native
> method]   
>     NSApplication.sendEvent(NSEvent) line: 128   
>     Display.readAndDispatch() line: 3666   
>     PartRenderingEngine$9.run() line: 1151   
>     Realm.runWithDefault(Realm, Runnable) line: 332   
>     PartRenderingEngine.run(MApplicationElement, IEclipseContext) line:
> 1032   
>     E4Workbench.createAndRunUI(MApplicationElement) line: 148   
>     Workbench$5.run() line: 636   
>     Realm.runWithDefault(Realm, Runnable) line: 332   
>     Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 579   
>     PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line:
> 150   
>     Application.start(IApplicationContext) line: 51   
>     EclipseAppHandle.run(Object) line: 196   
>     EclipseAppLauncher.runApplication(Object) line: 134   
>     EclipseAppLauncher.start(Object) line: 104   
>     EclipseStarter.run(Object) line: 380   
>     EclipseStarter.run(String[], Runnable) line: 235   
>     NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
> available [native method]   
>     NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62   
>     DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43   
>     Method.invoke(Object, Object...) line: 497   
>     Main.invokeFramework(String[], URL[]) line: 648   
>     Main.basicRun(String[]) line: 603   
>     Main.run(String[]) line: 1465   
>     Main.main(String[]) line: 1438   
>
>
> The question would be : how can we avoid such thing to happen ?



Mime
View raw message