Matthias Epheser wrote:
As Simone mentioned we are currently working together on the repeater pagination. I want to explain shortly how it works what problems still exist.
This is awesome!


Pagination can now be achieved by just adding a <fd:pages initial="1" size="20"/> tag to the repeater's definition. I added repeater actions as well for first, previous, next and last page.
What about:
- goto a specific page action
- change page size action

The actual pageLoad/pageSave takes place in the binding. A storage area is used there to cache updated rows on page change. Once the user submits, the actual saving to the JXPathContext takes place.

To support really big lists managed by a persistency frameworks (like in the application Simone mentioned) we implemented the possibility to use "lazy collections". A lazy collection is simply an implementation of the java.util.Collection interface that knows how to handle size()- or get(i)- calls without fetching the whole data from the db.

There are two "levels" of lazy collections:

1. OnlyALittleBitLazy(tm) which fetches full collection contents on first collection call ( even collection.size() ); This collection is no use for paging - does not scale.

2. TotallyLazy(tm) which fetches all entity ids on first collection call and then uses separate queries to fetch EACH entity. This one seriously faces the famous (n+1) problem (apart from the fact that if you want
to paginate through a table of 100k entries you won't select 100k
entities but still you'll have a collection of 100k ids).

In order to display 100 entries in a particular page 100 more queries are needed. Performance goes down a lot.


I would like to propose something else:
public interface ValueListProvider() {
public List getRows( SomeContextForFilteringAndSorting context, long offset, long rowCount ); public long getTotalRowCount( SomeContextForFilteringAndSorting context );
}

This way you always have only two queries to run:

select * from Entity e where e.name like '%filter%' limit 100 offset 3
select count( * ) from Entity e where e.name like '%filter%'

and you can always wrap your lazy collection with ValueListProvider.


Another feature we want to implement is sorting, more precisely displaying sorted rows. It's not our intention to actually store the data to the object in a different order but to make it possible for the user to click on the column-header and get the rows displayed in ascendant/descendant order. We think we need some data-providing class that act as a layer between the binding storage and the repeater rows, that provides sort(columnName) and getRows(from,to) or similar. We now have to evaluate how this could be done in a decent way and keep the door open for our lazy list here.

Concerning this we face some "indexing problems" after a page change. Row additions/deletions and sorting change the order and count of rows, therefore we need a technique to obtain the right start-index when we jump to a custom page. It's not guaranteed that our start-index in the collection is 100 if pageSize=10 and requestedPage=10.

It may be a little bit too hot here because I cannot think of a reason why. Why is that?


These are our thoughts about it:

The previous and next actions are still able work because we could remember the fist and last index of the current page and start relative to them to fetch the next n rows.

First and last page could work the same way using 0 and collection.size().

First page is of course 0
Last page could be: java.lang.Math.ceil( collectionSize / pageSize ) - 1 ) * pageSize


So the problem is located in the goto-widget. We are thinking of a couple possible solutions. Precise positioning would only be possible if we use iteration and check all rows to compute the correct starting point. Another solution would be to use "approximative" starting indexes. That means that, facing large collections, we always take pageSumber*pageSize as the starting index after the custom-page action. This approach solves the (maybe resource intensive) iteration problem but could provide results that are not exact. Another option would be to move this problem to the not yet existing data-providing class I mentioned in the sorting part.


Do you think it's a real problem to have not exact starting indexes while jumping between pages in big repeaters?

I would rather have a little bit inexact results than something that would kill my server if 100 users used it at the same time.

--
Leszek Gawron                                      [EMAIL PROTECTED]
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Reply via email to