To illustrate a second type of batching, we modify the test query from the last section. The only difference is in the choice of string to pass into the query so that the result of the query is a large set. In this test, the result set is over 25,000 strings. The client query is still significantly longer than the server query, but even the server query now takes several seconds in absolute time.
There is no reason to make the user wait for the whole result set to be transferred before displaying some of the results. Altering the application to send results in batches is quite easy. You need to add an intermediate object to hold the results on the server, which can send the results in batches as required.
public class QueryResultHolderImpl implements QueryResultHolder { String[ ] results; int sentSoFar; public QueryResultHolderImpl(String[ ] results) { this.results = results; sentSoFar = 0; } public resultSize( ){return results.length;} public nextBatch(int batchSize) { String[ ] batch = new String[batchSize]; System.arraycopy(results, sentSoFar, batch, 0, batchSize); sentSoFar += batchSize; return batch; } }
You also need to add methods in the server object to support this batching object:
public QueryResultHolder getBatchedServerQuery(String obj) { return new QueryResultHolderImpl(getQuery(obj, getQueryArray( ))); }
Now the client has the flexibility to request batches of results. The initial call to the query returns as fast as possible, with minimal network-transfer overhead: only one small proxy object is sent back in reply to the query. Note that the assumption here is that the QueryResultHolder object is not serialized when returned; instead, a proxy to the real object is passed to the client. The actual QueryResultHolder object holding the result set remains on the server. By wrapping the QueryResultHolder proxy, the optimization can be made completely transparent.