Hi Fabian,

ok. I was trying to implement incremental search (search as you type) with
a filtered data model. Works like a charm, as long as there are not too many
data, but is just much too slow for a longer table.

I now implemented a brute-force filter, looping over the data array and
pushing (substr) matching rows onto a new array and then calling
dataModel.setData(newArray). This is fast enough with a 2 column and 50,000
row table, to call it on every input-event in a textfield search field. At
least with FF 3.5.1 it is fast enough, haven't tested it with older browsers
or IE. But there is a lot of room for improvement, e.g. using a timer and
only searching after the user stops typing for a couple of hundred msecs).

The bugs you attached pretty much sum up what I observe/suspect in respect
to performance.

My comments about naming, etc, still apply, although they might be addressed
in the smart table model (which I guess I should give a try). It would be
cool to have something like this included into the main tree, as the
Filtered model seems to have a variety of issues that limit its usefulness.

Cheers,
Fritz

On Wed, 5 Aug 2009, Fabian Jakobs wrote:

> Hi Fritz,
>
> thank you for your thorough analysis. We know that the filtered table
> model is not optimal. There are a couple of bugs to improve the
> performance of the model by removing unnecessary computations [1-3].
> Recently Dave Baggett has proposed his "Smart" table model as
> replacement for the filtered table model [4]. Unfortunately we will not
> be able to fix these issues in the short term.
>
> Best Fabian
>
> [1] <http://bugzilla.qooxdoo.org/show_bug.cgi?id=999>
> [2] <http://bugzilla.qooxdoo.org/show_bug.cgi?id=2431>
> [3] <http://bugzilla.qooxdoo.org/show_bug.cgi?id=790>
> [4] <http://bugzilla.qooxdoo.org/show_bug.cgi?id=2474>
>
>> Hi,
>>
>> with SVN-trunk checkout 19765:
>>
>> I am using qx.ui.table.model.Filtered.addRegex() with the following
>> observations:
>>
>> 1) The filter is executed immediately after the call to addRegex(), without
>>     a call to applyFilters(). The API would suggest otherwise, which would
>>     probably make sense performance wise if several filters are needed on the
>>     same table model.
>>
>> 2) Calling addRegex() twice on the same column with different filter values
>>     leads to replacement of the first filter. Which is fine for my current
>>     application, but not what I would expect from the verb "add".
>>
>>     At least it should be document.
>>
>>     If addRegex() would indeed add (to a stack of) filters, I guess there
>>     would be some need to explicitely remove a filter.
>>
>> 3) addRegex() works also exactly the same as described above with a simple
>>     table model (which according to the API it should not).
>>
>> 4) The naming of the addFilter functions is inconsistent. Shouldn't it be
>>     addRegexFilter() and addNotRegexFilter() ?
>>
>> 5) Feature request: a function  addSubstringFilter() would be useful with
>>     substring matching instead of Regex matching, e.g. when working with a
>>     SQL backend that might not support Regexes.
>>
>> Here is a code snippet which should reproduce the above behaviour:
>>
>>          var tableModel = new qx.ui.table.model.Simple();
>> //        var tableModel = new qx.ui.table.model.Filtered();
>>          tableModel.setColumns([ this.tr("Location"),
>>                              this.tr("Team"),
>>                              this.tr("Client"),
>>                                  this.tr("User")
>>                                ], // headers
>>                                ['location', 'team', 'client', 'user'] //IDs
>>                               );
>>          // Customize the table column model.  We want one that automatically
>>          // resizes columns.
>>          var custom =  {
>>              tableColumnModel : function(obj) {
>>                  return new qx.ui.table.columnmodel.Resize(obj);
>>              }
>>          };
>>
>>          var outputTable = new qx.ui.table.Table(tableModel, custom);
>>          with (outputTable) {
>>              set({ padding: 0,
>>                showCellFocusIndicator: false,
>>                    keepFirstVisibleRowComplete: true,
>>                    columnVisibilityButtonVisible: false,
>>                    statusBarVisible: false
>>              });
>>              setMetaColumnCounts([1, -1]);
>>              
>> getSelectionModel().setSelectionMode(qx.ui.table.selection.Model.MUL
>> TIPLE_INTERVAL_SELECTION);
>>
>>              var tcm = getTableColumnModel();
>>
>>              // Obtain the behavior object to manipulate
>>              var resizeBehavior = tcm.getBehavior();
>>
>>              // The default is { width:"1*" } so this one is not necessary:
>>              resizeBehavior.set(0, { width:"1*"});
>>              resizeBehavior.set(1, { width:"1*" });
>>              resizeBehavior.set(2, { width:"1*"});
>>              resizeBehavior.set(3, { width:"1*" });
>>          };
>>          this.add(outputTable);
>>
>>          var testData = [
>>              ['Olten', 'O+P',  'U12345', 'zaucker'],
>>              ['Olten',  'O+P',  'U12345', 'oetiker'],
>>              ['Bern',   'SCIS', 'U23456', 'lepore'],
>>              ['Olten',  'O+P',  'U34567', 'plessl'],
>>              ['Bern',   'SCIS', 'U45678', 'henning'],
>>              ['Bern',   'SCIS',  'U56789', 'Frera']
>>                         ];
>>          tableModel.setData(testData);
>>
>>          this._filter = new qx.ui.form.Button(this.tr("Filter"));
>>
>>          this._filter.addListener('execute',function (e) {
>>              var location = 'Olten';
>>              var team     = 'O+P';
>>          var client   = null;
>>          var user     = null;
>>
>>              if (location != null) {
>>                  tableModel.addRegex(location, 'location', true); 
>> //ignorecase
>>              }
>>              if (team != null) {
>>                  tableModel.addRegex(team, 'team', true); //ignorecase
>>                  }
>>              if (client != null) {
>>                  tableModel.addRegex(client, 'client', true); //ignorecase
>>              }
>>              if (user != null) {
>>                  tableModel.addRegex(user, 'user', true); //ignorecase
>>              }
>> //            tableModel.applyFilters();
>>          });
>>
>> Cheers,
>> Fritz
>>
>>
>
>
>

-- 
Oetiker+Partner AG              tel: +41 62 775 99 03 (direct)
Fritz Zaucker                        +41 62 775 99 00 (switch board)
Aarweg 15                            +41 79 675 06 30 (mobile)
CH-4600 Olten                   fax: +41 62 775 99 05
Schweiz                         web: www.oetiker.ch

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
qooxdoo-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

Reply via email to