@@ -77,16 +77,65 @@ assign(Img.prototype, EventEmitter.prototype, {
7777} ) ;
7878
7979var kInstancePoolLength = 300 ;
80- var _instancePool = [ ] ;
8180
82- function getPooledImage ( src ) {
83- for ( var i = 0 , len = _instancePool . length ; i < len ; i ++ ) {
84- if ( _instancePool [ i ] . getOriginalSrc ( ) === src ) {
85- return _instancePool [ i ] ;
81+ var _instancePool = {
82+ length : 0 ,
83+ // Keep all the nodes in memory.
84+ elements : {
85+
86+ } ,
87+
88+ // Push with 0 frequency
89+ push : function ( hash , data ) {
90+ this . length ++ ;
91+ this . elements [ hash ] = {
92+ hash : hash , // Helps identifying
93+ freq : 0 ,
94+ data : data
95+ } ;
96+ } ,
97+
98+ get : function ( path ) {
99+ var element = this . elements [ path ] ;
100+
101+ if ( element ) {
102+ element . freq ++ ;
103+ return element . data ;
104+ }
105+
106+ return null ;
107+ } ,
108+
109+ // used to explicitely remove the path
110+ removeElement : function ( path ) {
111+ // Now almighty GC can claim this soul
112+ var element = this . elements [ path ] ;
113+ delete this . elements [ path ] ;
114+ this . length -- ;
115+ return element ;
116+ } ,
117+
118+ _reduceLeastUsed : function ( least , currentHash ) {
119+ var current = _instancePool . elements [ currentHash ] ;
120+
121+ if ( least . freq > current . freq ) {
122+ return current ;
86123 }
124+
125+ return least ;
126+ } ,
127+
128+ popLeastUsed : function ( ) {
129+ var reducer = _instancePool . _reduceLeastUsed ;
130+ var minUsed = Object . keys ( this . elements ) . reduce ( reducer , { freq : Infinity } ) ;
131+
132+ if ( minUsed . hash ) {
133+ return this . removeElement ( minUsed . hash ) ;
134+ }
135+
136+ return null ;
87137 }
88- return null ;
89- }
138+ } ;
90139
91140var ImageCache = {
92141
@@ -96,14 +145,14 @@ var ImageCache = {
96145 * @return {Img }
97146 */
98147 get : function ( src ) {
99- var image = getPooledImage ( src ) ;
148+ var image = _instancePool . get ( src ) ;
100149 if ( ! image ) {
101- // Simple FIFO queue
150+ // Awesome LRU
102151 image = new Img ( src ) ;
103152 if ( _instancePool . length >= kInstancePoolLength ) {
104- _instancePool . shift ( ) . destructor ( ) ;
153+ _instancePool . popLeastUsed ( ) . destructor ( ) ;
105154 }
106- _instancePool . push ( image ) ;
155+ _instancePool . push ( image . getOriginalSrc ( ) , image ) ;
107156 }
108157 return image ;
109158 }
0 commit comments