Hi,

        Just wanted to show you an example of CachedByteArrayResource at work...

Here is an image gallery: http://www.desktopbeautifier.com/Main?bookmarkablePage=desktopbeautifier.web.gallery.Page&theme=80

Previously it would take 5+ seconds for each page refresh. I did some DB optimization as well as applying CachedByteArrayResource to the thumbnail photos and as you can now see the page refresh is about one second. Most importantly, it *feels* much faster.

So what changed exactly? Well, previously all the thumbnails were being generated at Page render-time. Now, thanks to CachedByteArrayResource, the thumbnails are lazily-initialized so the user sees the page loading almost instantenously, followed by the separate image downloads. The perceived response time is much improved!

I've attached the source code for CachedByteArrayResource for your review. I'd like to know if there is interest in bundling this class into Wicket core or elsewhere. Let me know what you think!

Gili
--
http://www.desktopbeautifier.com/
/*
 * CachedByteArrayResource.java
 *
 * Created on August 19, 2005, 2:46 PM
 */

package desktopbeautifier.web.gallery;

import java.lang.ref.SoftReference;
import wicket.resource.DynamicByteArrayResource;
import wicket.util.time.Time;

/**
 * A CachedByteArrayResource is ideal for data that is expensive to generate or
 * is streamed from an expensive source (such as a database connection or a
 * socket). When a CachedByteArrayResource is serialized, the cache is
 * transient, which means it will disappear when the resource is sent over the
 * wire and then will be recreated when required.
 *
 * Use this class when the data and content-type are not known in advance and
 * generating them is an expensive operation.
 *
 * @author Gili Tzabari
 */
public abstract class CachedByteArrayResource extends DynamicByteArrayResource
{
  /**
   * Cached data.
   */
  private transient SoftReference<byte[]> data;
  /**
   * Content-type of cached data.
   */
  private transient String contentType;


  /**
   * Creates a new CachedByteArrayResource.
   */
  public CachedByteArrayResource()
  {}

  /**
   * Sets the cached data.
   */
  protected void setData(byte[] data)
  {
    this.data = new SoftReference(data);
    setLastModifiedTime(Time.now());
  }

  /**
   * [EMAIL PROTECTED]
   *
   * Due to the fact that SoftReferences are used internally, one must be
   * especially careful when retrieving the resource data and content-type.
   * To ensure that the two are consistent with one another you must first
   * invoke getData(), use a strong reference to keep it alive, then invoke
   * getContentType() to get the corresponding content-type.
   */
  @Override
    protected byte[] getData()
  {
    byte[] result;
    if (data!=null)
      result = data.get();
    else
      result = null;
    if (result==null)
      result = generateData();
    return result;
  }

  /**
   * Returns the resource content-type.
   *
   * Due to the fact that SoftReferences are used internally, one must be
   * especially careful when retrieving the resource data and content-type.
   * To ensure that the two are consistent with one another you must first
   * invoke getData(), use a strong reference to keep it alive, then invoke
   * getContentType() to get the corresponding content-type.
   */
  @Override
    public String getContentType()
  {
    // Initialize the data if necessary
    byte[] result = getData();

    return contentType;
  }

  /**
   * Sets the cached data content-type.
   */
  protected void setContentType(String value)
  {
    contentType = value;
  }

  /**
   * [EMAIL PROTECTED]
   */
  @Override
    public void invalidate()
  {
    super.invalidate();
    data = null;
  }

  /**
   * Invokes setData(), setContentType() and returns a reference to
   * the data.
   *
   * @return the data
   */
  protected abstract byte[] generateData();
}

Reply via email to