Implemented consolidation and extension of requests, code does currently not check which range requests are still pending

This commit is contained in:
Andreas Stöckel 2012-03-23 16:30:29 +00:00
parent 2e3d740da7
commit 1dec823e45
2 changed files with 159 additions and 16 deletions

View File

@ -51,16 +51,33 @@ var et2_dataview_controller = Class.extend({
// server.
this._lastModification = null;
// Timer used for queing fetch requests
this._queueTimer = null;
// Array used for queing the requests
this._queue = [];
// Register the dataFetch callback
this._grid.setDataCallback(this._gridCallback, this);
},
destroy: function () {
this._clearTimer();
this._super();
},
/**
* The update function queries the server for changes in the currently
* managed index range -- those changes are then merged into the current
* view without a complete rebuild of every row.
*/
update: function () {
// Clear the fetch queue
this._queue = [];
this._clearTimer();
// Get the currently visible range from the grid
var range = this._grid.getIndexRange();
@ -72,7 +89,7 @@ var et2_dataview_controller = Class.extend({
// Require that range from the server
this._queueFetch(range.top, range.bottom - range.top + 1,
this._lastModification !== null);
this._lastModification !== null, true);
},
/**
@ -205,7 +222,6 @@ var et2_dataview_controller = Class.extend({
// Queue fetching that data range
if (needsData !== false)
{
console.log("<--> Calling _queueFetch: ", needsData, _idxEnd - needsData + 1);
this._queueFetch(needsData, _idxEnd - needsData + 1, false);
}
},
@ -213,21 +229,139 @@ var et2_dataview_controller = Class.extend({
/**
*
*/
_queueFetch: function (_start, _numRows, _refresh) {
// Sanitize the request
_start = Math.max(0, _start);
_numRows = Math.min(this._grid.getTotalCount(), _start + _numRows)
- _start;
_queueFetch: function (_start, _numRows, _refresh, _immediate) {
// Context used in the callback function
var ctx = { "self": this, "start": _start, "count": _numRows };
// Force immediate to be false
_immediate = _immediate ? _immediate : false;
// _immediate = true;
// Build the query
var query = { "start": _start, "num_rows": _numRows, "refresh": _refresh };
// Push the request onto the request queue
this._queue.push({
"start": _start,
"num_rows": _numRows,
"refresh": _refresh
});
// Start the queue timer, if this has not already been done
if (this._queueTimer === null && !_immediate)
{
var self = this;
this._queueTimer = window.setTimeout(function () {
self._flushQueue();
}, ET2_DATAVIEW_FETCH_TIMEOUT);
}
if (_immediate)
{
this._flushQueue();
}
},
_flushQueue: function () {
function consolidateQueries(_q) {
var didConsolidation = false;
var _new = [];
var skip = {};
for (var i = 0; i < _q.length; i++)
{
var r1 = et2_range(_q[i].start, _q[i].num_rows);
var intersected = false;
for (var j = i + 1; j < _q.length; j++)
{
if (skip[j])
{
continue;
}
var r2 = et2_range(_q[j].start, _q[j].num_rows);
if (et2_rangeIntersect(r1, r2))
{
var n = et2_bounds(Math.min(r1.top, r2.top),
Math.max(r1.botom, r2.bottom));
_new.push({
"start": n.top,
"num_rows": n.bottom - n.top + 1,
"refresh": _q[i].refresh
});
skip[i] = true;
skip[j] = true;
intersected = true;
}
}
if (!intersected)
{
_new.push(_q[i]);
skip[i] = true;
}
}
if (didConsolidation) {
return consolidateQueries(_new);
}
return _new;
}
// Clear any still existing timer
this._clearTimer();
// Calculate the refresh flag (refresh = false is stronger)
var refresh = true;
for (var i = 0; i < this._queue.length; i++)
{
refresh = refresh && this._queue[i].refresh;
}
// Extend all ranges into bottom direction, initialize the queries array
for (var i = 0; i < this._queue.length; i++)
{
this._queue[i].num_rows += 10;
this._queue[i].refresh = refresh;
}
// Consolidate all queries
var queries = consolidateQueries(this._queue);
// Execute all queries
for (var i = 0; i < queries.length; i++)
{
// Sanitize the requests
queries[i].start = Math.max(0, queries[i].start);
queries[i].num_rows = Math.min(this._grid.getTotalCount(),
queries[i].start + queries[i].num_rows) - queries[i].start;
// Context used in the callback function
var ctx = {
"self": this,
"start": queries[i].start,
"count": queries[i].num_rows
};
// Call the callback
this._dataProvider.dataFetch(queries[i], this._lastModification,
this._fetchCallback, ctx);
}
// Flush the queue
this._queue = [];
},
_clearTimer: function () {
// Reset the queue timer upon destruction
if (this._queueTimer)
{
window.clearTimeout(this._queueTimer);
this._queueTimer = null;
}
// Call the callback
this._dataProvider.dataFetch(query, this._lastModification,
this._fetchCallback, ctx);
},
/**
@ -322,7 +456,14 @@ var et2_dataview_controller = Class.extend({
// of that entry is unknown, simply update the entry.
current.uid = _order[i];
current.idx = idx;
this._insertDataRow(current, true);
// Only update the row, if it is displayed (e.g. has a "loading"
// row displayed) -- this is needed for prefetching
if (current.row)
{
this._insertDataRow(current, true);
}
mapIdx++;
}
else if (current.uid !== _order[i])

View File

@ -327,7 +327,9 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
columnPreference = negated ? pref.substring(1) : pref;
}
}
var columnDisplay = et2_csvSplit(columnPreference,null,",");
var columnDisplay = typeof columnPreference === "string"
? et2_csvSplit(columnPreference,null,",") : columnPreference;
// Adjusted column sizes
var size = {};