Use Load-On-Demand to Handle Huge Data

From Documentation
DocumentationSmall Talks2008JuneUse Load-On-Demand to Handle Huge Data
Use Load-On-Demand to Handle Huge Data

Author
Marcos de Sousa, Senior Developer, Banco Comercial e de Investimentos (BCI Fomento), one of the largest private financial groups in Mozambique.
Date
June 13, 2008
Version
Applicable to zk-2.4.0 and later.


The Issue

A list box is used to display a number of items in a list. The list box and grid component support the paging intrinsically. If you have a list box with many items, for example 1.000.000 items, this is going to slow down your web application, it could potentially use a lot of memory on the server, limiting the number of users that can be supported at any time. This is what we don’t want to happen. So let´s fix it.


The Solution

Pagination is the simplest and most common way to break up large amounts of data into more manageable chunks. Pagination is a key part of Web Application design, both from the User Interface perspective (to manage limited screen real estate) and from the server perspective (to process large result sets efficiently, without causing resource spikes or servicing delays). ZK has a Basic Component called Paging. A paging component is used to separate long content into multiple pages. To solve the problem we need to specify a paging component explicitly.


Creating the Pages

I will revisit the code provided in ZK_2.x.x_.2B_Spring_2.x.x_.2B_Hibernate_3.x_.2B_JUnit_Test First let´s check how to use the list box component with paging intrinsically:

<?xml version="1.0" encoding="UTF-8"?>
<window title="Listbox with Paging Explicitly" border="normal"
  use="com.wikibook2.ui.EmployeeUI">
  <listbox id="lstEmployee" width="350px" checkmark="true">
    <listhead sizable="true">
      <listheader label="ID" sort="auto" />
      <listheader label="Full Name" sort="auto" />
      <listheader label="User Name" sort="auto" />
    </listhead>
  </listbox>  
</window>

Now, we want to use the list box with a paging component explicitly:

<?xml version="1.0" encoding="UTF-8"?>
<window title="Listbox with Paging Explicitly" border="normal"
  use="com.wikibook2.ui.EmployeeUI">
  <listbox id="lstEmployee" width="350px" checkmark="true">
    <listhead sizable="true">
      <listheader label="ID" sort="auto" />
      <listheader label="Full Name" sort="auto" />
      <listheader label="User Name" sort="auto" />
    </listhead>
  </listbox>
  <paging id="pagEmployee" pageSize="30" />
</window>

The only difference is, instead of we specify “mold="paging"” we don’t specify nothing, and in addition we use the paging component explicitly “<zk:paging id="pagEmployee" pageSize="30"/>”. It’s all to the User Interface.


Load-On-Demand

Let´s take a look to the EmployeeUI class:

package com.wikibook2.ui;

public class EmployeeUI extends SimpleWindow implements AfterCompose {
  private final String LST_EMPLOYEE = "lstEmployee";
  private final String PAG_EMPLOYEE = "pagEmployee";
  private final String MAN_EMPLOYEE = "employeeManager";
  private GenericManager employeeManager;

  public EmployeeUI() {
    employeeManager = (GenericManager) SpringUtil.getBean(MAN_EMPLOYEE);
  }

  public void afterCompose() {
    Paging pag = getPaging(PAG_EMPLOYEE);
    pag.setTotalSize(employeeManager.count().intValue());
    final int PAGE_SIZE = pag.getPageSize();
    // Show Listbox with first PAGE_SIZE
    redraw(0, PAGE_SIZE);
    pag.addEventListener("onPaging", new EventListener() {
      public void onEvent(Event event) {
        	PagingEvent pe = (PagingEvent) event;
        	int pgno = pe.getActivePage();
        	int ofs = pgno * PAGE_SIZE;        	
        	// Redraw current paging
        	redraw(ofs, PAGE_SIZE);
      	}
    	});
  }

  private void redraw(int firstResult, int maxResults) {
    Listbox lst = getListbox(LST_EMPLOYEE);
    lst.getItems().clear();
    List list = employeeManager.getAll(DetachedCriteria
        .forClass(Employee.class), firstResult, maxResults);
    for (Employee employee : list) {
      Listitem li = new Listitem();
      li.setValue(employee);
      li.appendChild(new Listcell("" + employee.getId()));
      li.appendChild(new Listcell(employee.getFullname()));
      li.appendChild(new Listcell(employee.getUsername()));
      lst.appendChild(li);
    }
  }
}


As you can see, the main idea is Query Based Strategy, where results are fetched from Database on demand as the user pages and send to the client. This means that a new query will be run each time the user moves between pages so there is a performance overhead with this approach. However, because of the lower memory usage, this solution is also more scalable and that is typically a more important consideration when it comes to web applications. By implementing AfterCompose, we perform some initialization:

  • Set the total number of employees.
  • Draw the list box with first employees in the initial page.
  • Add an Event Listener onPaging to the paging component.

The onPaging event, is sent with an instance of PagingEvent to the paging component, then, we retrieve the active page (starting from 0) and the index of the first visible employee by multiple the active page with the paging page size. Once we have the offset of current page it is time to redraw the list box by first clear all employees and then retrieve the new chunk of employees. Remember that, the AfterCompose is a bit faster since no need to fork another thread while listening to the onCreate event is free to suspend and resume the execution.


Summary

This Small Talk has introduced you the power of Paging Component, how to implement paging for listbox with performance when with many items. You can found advantages of Paging Component in How_to_implement_paging_for_listboxes_with_many_items I hope you’ve enjoyed this Small Talk and that influenced to you start explore ZK further. I’ve found ZK to be a very productive framework in the development of web applications for both intranet and internet.


Download

Download the load-on-demand.zip. After download the project, read the “readme.pdf” to know how to deal with the project wikibook2.


Ruler.gif


Marcos de Sousa , work in the development area more than five years. Work as Senior Developer at Banco Comercial e de Investimentos ( BCI Fomento ), one of the largest private financial groups in Mozambique. Studied Computer Science (Eduardo Mondlane University – Informatics Course (5th year)).




Copyright © Marcos de Sousa. This article is licensed under GNU Free Documentation License.