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