Skip to content

Commit

Permalink
LRU cache refinements, including consolidating cache fill calls
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuels committed Oct 11, 2012
1 parent a8aaf7f commit a21d47e
Showing 1 changed file with 52 additions and 17 deletions.
69 changes: 52 additions & 17 deletions src/JBrowse/Store/LRUCache.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
define([
'dojo/_base/declare'
'dojo/_base/declare',
'dojo/_base/array'
],
function( declare ) {
function( declare, array ) {

return declare( null,

Expand Down Expand Up @@ -34,10 +35,18 @@ return declare( null,
// each end of a doubly-linked list, sorted in usage order
this._cacheOldest = null;
this._cacheNewest = null;

// we aggregate cache fill calls that are in progress, indexed
// by cache key
this._inProgressFills = {};
},

_log: function() {
//console.log.apply( console, arguments );
// if( typeof arguments[0] == 'string' )
// while( arguments[0].length < 15 )
// arguments[0] += ' ';

// console.log.apply( console, arguments );
},

get: function( inKey, callback ) {
Expand All @@ -46,19 +55,11 @@ return declare( null,
var record = this._cacheByKey[ key ];
if( !record ) {
// call our fill callback if necessary

this._log( 'cache miss', key );

if( this.fill ) {
this.fill( inKey, dojo.hitch(this, function( value ) {
if( value ) {
this.set( inKey, value );
}
callback( value );
}));
}
else {
callback( null );
}
this._attemptFill( inKey, key, callback );

return;
}

Expand All @@ -80,19 +81,45 @@ return declare( null,
callback( record.value );
},

_attemptFill: function( inKey, key, callback ) {
if( this.fill ) {
var fillRecord = this._inProgressFills[ key ] || { callbacks: [], running: false };
fillRecord.callbacks.push( callback );
if( ! fillRecord.running ) {
fillRecord.running = true;
this.fill( inKey, dojo.hitch( this, function( value ) {
delete this._inProgressFills[ key ];

if( value ) {
this._log( 'cache fill', key );
this.set( inKey, value );
}
array.forEach( fillRecord.callbacks, function( cb ) {
cb.call(this, value);
}, this );
}));
this._inProgressFills[ key ] = fillRecord;
}
}
else {
this._log( "cache can't fill", key );
callback( undefined );
}
},

set: function( inKey, value ) {
var key = this._keyString( inKey );
if( this._cacheByKey[key] ) {
return;
}
this._log( 'cache fill', key, value );

// make a cache record for it
var record = {
value: value,
key: key,
size: this._size( value )
};
this._log( 'cache set', key, record, this.size );

// evict items if necessary
this._prune( record.size );
Expand Down Expand Up @@ -134,6 +161,9 @@ return declare( null,
}
else if( sizeType == 'function' ) {
return value.size();
}
else if( value.byteLength ) {
return value.byteLength;
} else {
var sum = 0;
for( var k in value ) {
Expand All @@ -143,15 +173,19 @@ return declare( null,
}
}
return sum;
} else if( type == 'string' ) {
return value.length;
} else {
return 1;
}
},

_prune: function( newItemSize ) {
while( this.size + newItemSize > this.maxSize ) {
while( this.size + (newItemSize||0) > this.maxSize ) {
var oldest = this._cacheOldest;
if( oldest ) {
this._log( 'cache evict', oldest );

// update the oldest and newest pointers
if( ! oldest.next ) // if this was also the newest
this._cacheNewest = oldest.prev; // probably undef
Expand All @@ -176,7 +210,8 @@ return declare( null,
this.size -= oldest.size;
} else {
// should not be reached
throw "what is this i don't even";
console.error("cache error!");
return;
}
}
}
Expand Down

0 comments on commit a21d47e

Please sign in to comment.