Re: [REVIEW REQUEST] RT-33442: isSelected in TableViewSelectionModel is called too many times

2013-10-21 Thread Jeff Martin
I'm late to this discussion, and I don't see anything wrong with the 
selectRange() API, but perhaps another option worth considering would be to add 
a DisableSelectionEvents or CoalesceSelectionEvents attribute.

The only advantage to that I can think of is that it could allow bulk selection 
of non-contiguous cells which might otherwise also exhibit the slowdown.

jeff


On Oct 21, 2013, at 8:35 AM, Stephen F Northover steve.x.northo...@oracle.com 
wrote:

 Hi Johnathan,
 
 1) Is it possible to do the optimization without adding API (ugly but safe)?
 2) Another alternative (ugly) is to add the API but make it return a boolean 
 indicating whether it happened or not.
 3) It seem really weird to me that you can't convert from Column to index and 
 back again.  What about getColumns()?
 
 Steve
 
 On 2013-10-21 5:04 AM, Jonathan Giles wrote:
 The only reason why we tended to prefer TableColumn* in the API over ints is 
 that the TableColumn approach more clearly defined what columns were meant 
 to be selected (both because you could read directly back from the argument 
 list and because there was never any chance that the int positions could 
 become corrupted if the column order were to ever change in the middle of an 
 operation and the int values would no longer be valid).
 
 In general it is a relatively weak argument (but an argument nonetheless), 
 so I'm not massively concerned one way or the other, except from an API 
 consistency point of view, where the TableColumn approach definitely is more 
 consistent. I figure I'm about to call it a night here, so I'll wait and see 
 what feedback is received over night and will hopefully have the go-ahead 
 from the community to finish this changeset off and push tomorrow :-)
 -- Jonathan
 On 21/10/2013 9:53 p.m., Johan Vos wrote:
 I would prefer to have the selectRange (int, int, int, int) call. I know 
 TableColumn* is used heavily in the API, but it doesn't sound right to me 
 to use a primitive (int) for a row-selector and an Object for a 
 column-selector.
 Having a no-op on the abstract call sounds ok, everybody happy.
 
 Leaving the API as it is now is not really an option IMHO, as performance 
 indeed becomes a problem for large tables.
 
 - Johan
 
 
 2013/10/20 Jonathan Giles jonathan.gi...@oracle.com 
 mailto:jonathan.gi...@oracle.com
 
On 19/10/2013 8:24 a.m., Jonathan Giles wrote:
 On 19/10/2013 2:13 a.m., Stephen F Northover wrote:
 If it is a noop, will it not break people when the system
calls it and
 it does nothing?
 Only the abstract TableSelectionModel is a no-op, the
implementations
 (one each for TableView and TreeTableView) will both override and
 provide the implementation that I already have in the patch for
 TableView. I would rather have the implementation in the base
class but
 this is not feasible due to requirements in looking up column
indices.
I looked into providing a default implementation in
TableSelectionModel,
but the problem is is that there just isn't enough data at this
level of
the API.
 
In short, the API could take two forms:
selectRange(int minRow, int minColumn, int maxRow, int maxColumn)
selectRange(int minRow, TableColumnBase minColumn, int maxRow,
TableColumnBase maxColumn)
 
Either implementation is possible (although at present I've
implemented
the first approach, but for consistency it is probably better we
use the
second approach as all other API uses TableColumn* to represent
columns,
not ints).
 
The problem is is that neither approach gives me what I want for a
default implementation, which would take the following form:
for (int row = minRow; row = maxRow; row++) {
for (int col = minColumn; col = maxColumn; col++) {
TableColumnBase column = getColumn(col);
select(row, column);
}
}
 
With the first API option (all ints), I am lacking the getColumn(..)
method to convert column indices to TableColumn instances.
With the second API option, I have no way of converting the two
TableColumnBase instances back into ints, and then I have the same
problem as with the first API.
 
Therefore, my options as far as I can see (and I'm happy to be wrong)
are to either not introduce this API and keep the performance
poor (for
now - hopefully we'll come up with a better solution in time) or to
introduce one of the two methods above and then have a no-op
implementation clearly documented in TableSelectionModel (with
the two
existing implementations in JavaFX 8.0 both implementing a far
more high
performance approach than we have currently).
 
Thoughts?
-- Jonathan
 
 
 
 
 



Re: [REVIEW REQUEST] RT-33442: isSelected in TableViewSelectionModel is called too many times

2013-10-21 Thread Jonathan Giles
I've added an updated patch to RT-33442. From the jira comment included
with the patch:

1) selectRange method in TableSelectionModel is now abstract (given that
TableSelectionModel is new in 8.0 this is fine).

2) selectRange argument list is now (int, TableColumnBase, int,
TableColumnBase)

3) TableViewSelectionModel API is now unfortunately the same (i.e. I
can't make the type TableColumn, which is more specific, and requires
casting inside the method)

4) I have ported the patch to also apply to TreeTableView.

5) The same problem in 3) also exists for TreeTableView.

I'll get a implementation review done by a controls team member, but a
+1 on the API choice would be appreciated.

-- Jonathan

On 22/10/2013 9:43 a.m., Stephen F Northover wrote:
 TableSelectionModel is new for JDK8 (at least according to the
 Javadoc).  If so, add the method as abstract and put implementations
 in the concrete subclasses, no?

 Steve

 On 2013-10-21 3:15 PM, Jonathan Giles wrote:

 On 22/10/2013 2:35 a.m., Stephen F Northover wrote:
 1) Is it possible to do the optimization without adding API (ugly
 but safe)?
 There are aspects of the optimisation that can be done without adding
 API. However, in my testing this API change is the most important of
 the changes, so without it there would be some, but much less,
 benefit of including the other changes.
 2) Another alternative (ugly) is to add the API but make it return a
 boolean indicating whether it happened or not.
 Sure, I'm fine with this if this is the desired approach.
 3) It seem really weird to me that you can't convert from Column to
 index and back again.  What about getColumns()?
 The reason why this is the case is that TableSelectionModel is
 control independent, so it does not have the TableView or
 TreeTableView available to it. If it did these translations would be
 trivial (and are done all the time). This is why TableSelectionModel
 is currently a no-op, whereas the actual TableSelectionModel
 implementations (hidden within TableView and TreeTableView) can do
 precisely this.

 -- Jonathan




Re: [REVIEW REQUEST] RT-33442: isSelected in TableViewSelectionModel is called too many times

2013-10-18 Thread Jonathan Giles
On 19/10/2013 2:13 a.m., Stephen F Northover wrote:
 If it is a noop, will it not break people when the system calls it and
 it does nothing?

Only the abstract TableSelectionModel is a no-op, the implementations
(one each for TableView and TreeTableView) will both override and
provide the implementation that I already have in the patch for
TableView. I would rather have the implementation in the base class but
this is not feasible due to requirements in looking up column indices.

 Further, what about discontinuous selections (ie. one item, then an
 unselected item, then a million selected items in a block).  You can
 do this on native Windows using Shift+Ctrl+Select but I see that this
 is not supported in the FX table.

I haven't included discontinuous selection in this round of performance
research, but in general the changes in the RT-33442 changeset will have
the same drastic improvement there as well. However, as you note, there
is not a full implementation of discontinuous selection implemented in
TableView yet, so the point is a little moot at this stage.

-- Jonathan


[REVIEW REQUEST] RT-33442: isSelected in TableViewSelectionModel is called too many times

2013-10-17 Thread Jonathan Giles
Hi all,

I know we're very late in the release, but I'm proposing the addition of
one new method to the TableSelectionModel abstract class, which will
have implementations provided by TableView and TreeTableView. The method
added into TableSelectionModel will be a no-op method by default (to
hopefully not break anyone), and I propose it should have the following
method signature:

public void selectRange(int minRow, int minColumn, int maxRow, int
maxColumn)

This method will be used internally, and by any interested end user, to
signal to the TableView/TreeTableView control to select all cells within
the range of (minRow, minColumn) - (maxRow, maxColumn), inclusive.

The reason why I want to introduce this is summed up well in RT-33442
and RT-33619. In short, given a big enough table, a shift+click can
essentially cause the TableView to hang whilst it selects all the cells
within the range. This is basically due to all the selection events
overloading the system. The benefit of introducing this method is that I
can make the selection essentially an atomic operation, which will
result in drastically less event noise.

To better understand what I mean, there is a patch attached to RT-33442
(rt33442_2.patch). This patch introduces this change, as well as a
number of other implementation changes. In doing so the selection
performance in this use case goes from crashing my test application
(presumably it would complete, but I give up after five minutes of
waiting) to taking under 1 second.

There is still more testing to be done, but after applying this patch
all controls unit tests continue to pass. Also, as noted in the jira
issue, this patch is incomplete as I have not ported the patch to also
cover TreeTableView.

So, after all that, should we add selectRange(minRow, minColumn, maxRow,
maxColumn) to JavaFX 8.0? If so, does anyone have an improved method
signature they can recommend? I will of course be writing unit tests to
cover this method and testing to ensure there are no regressions as best
I can.

Thanks,
-- Jonathan