Lazy is not always bad…

Lazy data-structures are structures that could be requested and are therefore not necessary loaded at request time.

Besides "lazy" data retrieval another important aspect of these data-structures are often the possibility to cache executed requests. To reduce http-requests on server-side it's necessary to cache the results of former requests on client-side.

To solve this problem a data-structure must be created on which specific ranges can be requested. Configured with a specific page size, data can be loaded with a constant size and requests therefore easily be cached.

The following uml-diagram shows the dependencies between the participants:

Requestable DataProvider

The data holder (AbstractRequestableDataProvider) stores the requests in a queue and processes them until the queue is empty.

public function request( range: Range ): Boolean
{
	if( isAreaRequested( range ) || isAreaLoaded( range ) )
	{
		return false;
	}
	else
	{
		// -- _fromPage is calculated in isAreaLoaded() (no second loop is needed for calculating _fromPage)
		_toPage = Math.ceil( range.end / _pageSize );
 
		var i: int = _fromPage;
 
		for( ; i < _toPage ; ++i )
		{
			_requestQueue.add( createDataProviderService( new ServiceRequest( new Range( i * _pageSize, ( i + 1 ) * _pageSize ) ) ) );
		}
 
		processServices();
 
		return true;
	}
}
protected function processServices(): void
{
	if( _isReady && !_requestQueue.isEmpty() )
	{
		_isReady = false;
 
		if( _currentService != null )
		{
			_currentService.removeObserver( this );
		}
 
		_currentService = IManageableDataService( _requestQueue.poll() );
		_currentService.addObserver( this );
		_currentService.start();
	}
}
public function isAreaLoaded( range: Range ): Boolean
{
	var start: int = range.start;
 
	// -- this calculation is placed here, because of performance task
	// -- instead there could be another loop for calculating _fromPage
	_fromPage = int( start / _pageSize );
 
	var len: int = range.end;
	var j: int = start;
 
	for( ; j < len ; ++j )
	{
		if( _list.getAt( j ) == null )
		{
			return false;
		}
 
		// -- to save data-requests that has already been executed
		if( j > 0 && j > start && j % _pageSize == 0 )
		{
			++_fromPage;
		}
	}
 
	return true;
}
public function isAreaRequested( range: Range ): Boolean
{
	var len: int = _requestQueue.size();
 
	while( --len > -1 )
	{
		if( range.isSubsetOf( IManageableDataService( _requestQueue.getAt( len ) ).serviceRequest.range ) )
		{
			return true;
		}
	}
 
	return false;
}

Leave a Reply

Formatting: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>