11import Immutable from 'immutable'
22import logging from '../logging'
3+ import { CacheEntry } from './cache'
34import { isImmutableValue } from '../immutable-helpers'
45import { toImmutable } from '../immutable-helpers'
56import { fromKeyPath , getStoreDeps , getComputeFn , getDeps , isGetter } from '../getter'
@@ -330,22 +331,21 @@ export function evaluate(reactorState, keyPathOrGetter) {
330331 }
331332
332333 // Must be a Getter
333- // if the value is cached for this dispatch cycle, return the cached value
334- if ( isCached ( reactorState , keyPathOrGetter ) ) {
335- // Cache hit
336- return evaluateResult (
337- getCachedValue ( reactorState , keyPathOrGetter ) ,
338- reactorState
339- )
340- }
341334
342- // evaluate dependencies
343- const args = getDeps ( keyPathOrGetter ) . map ( dep => evaluate ( reactorState , dep ) . result )
344- const evaluatedValue = getComputeFn ( keyPathOrGetter ) . apply ( null , args )
335+ const cache = reactorState . get ( 'cache' )
336+ var cacheEntry = cache . lookup ( keyPathOrGetter )
337+ const isCacheMiss = ! cacheEntry || isDirtyCacheEntry ( reactorState , cacheEntry )
338+ if ( isCacheMiss ) {
339+ cacheEntry = createCacheEntry ( reactorState , keyPathOrGetter )
340+ }
345341
346342 return evaluateResult (
347- evaluatedValue ,
348- cacheValue ( reactorState , keyPathOrGetter , evaluatedValue )
343+ cacheEntry . get ( 'value' ) ,
344+ reactorState . update ( 'cache' , cache => {
345+ return isCacheMiss ?
346+ cache . miss ( keyPathOrGetter , cacheEntry ) :
347+ cache . hit ( keyPathOrGetter )
348+ } )
349349 )
350350}
351351
@@ -375,57 +375,31 @@ export function resetDirtyStores(reactorState) {
375375 return reactorState . set ( 'dirtyStores' , Immutable . Set ( ) )
376376}
377377
378- /**
379- * Currently cache keys are always getters by reference
380- * @param {Getter } getter
381- * @return {Getter }
382- */
383- function getCacheKey ( getter ) {
384- return getter
385- }
386-
387378/**
388379 * @param {ReactorState } reactorState
389- * @param {Getter|KeyPath } keyPathOrGetter
390- * @return {Immutable.Map }
380+ * @param {CacheEntry } cacheEntry
381+ * @return {boolean }
391382 */
392- function getCacheEntry ( reactorState , keyPathOrGetter ) {
393- const key = getCacheKey ( keyPathOrGetter )
394- return reactorState . getIn ( [ 'cache' , key ] )
395- }
383+ function isDirtyCacheEntry ( reactorState , cacheEntry ) {
384+ const storeStates = cacheEntry . get ( 'storeStates' )
396385
397- /**
398- * @param {ReactorState } reactorState
399- * @param {Getter } getter
400- * @return {Boolean }
401- */
402- function isCached ( reactorState , keyPathOrGetter ) {
403- const entry = getCacheEntry ( reactorState , keyPathOrGetter )
404- if ( ! entry ) {
405- return false
406- }
407-
408- const storeStates = entry . get ( 'storeStates' )
409- if ( storeStates . size === 0 ) {
410- // if there are no store states for this entry then it was never cached before
411- return false
412- }
413-
414- return storeStates . every ( ( stateId , storeId ) => {
415- return reactorState . getIn ( [ 'storeStates' , storeId ] ) === stateId
386+ // if there are no store states for this entry then it was never cached before
387+ return ! storeStates . size || storeStates . some ( ( stateId , storeId ) => {
388+ return reactorState . getIn ( [ 'storeStates' , storeId ] ) !== stateId
416389 } )
417390}
418391
419392/**
420- * Caches the value of a getter given state, getter, args, value
393+ * Evaluates getter for given reactorState and returns CacheEntry
421394 * @param {ReactorState } reactorState
422395 * @param {Getter } getter
423- * @param {* } value
424- * @return {ReactorState }
396+ * @return {CacheEntry }
425397 */
426- function cacheValue ( reactorState , getter , value ) {
427- const cacheKey = getCacheKey ( getter )
428- const dispatchId = reactorState . get ( 'dispatchId' )
398+ function createCacheEntry ( reactorState , getter ) {
399+ // evaluate dependencies
400+ const args = getDeps ( getter ) . map ( dep => evaluate ( reactorState , dep ) . result )
401+ const value = getComputeFn ( getter ) . apply ( null , args )
402+
429403 const storeDeps = getStoreDeps ( getter )
430404 const storeStates = toImmutable ( { } ) . withMutations ( map => {
431405 storeDeps . forEach ( storeId => {
@@ -434,19 +408,11 @@ function cacheValue(reactorState, getter, value) {
434408 } )
435409 } )
436410
437- return reactorState . setIn ( [ 'cache' , cacheKey ] , Immutable . Map ( {
411+ return CacheEntry ( {
438412 value : value ,
439413 storeStates : storeStates ,
440- dispatchId : dispatchId ,
441- } ) )
442- }
443-
444- /**
445- * Pulls out the cached value for a getter
446- */
447- function getCachedValue ( reactorState , getter ) {
448- const key = getCacheKey ( getter )
449- return reactorState . getIn ( [ 'cache' , key , 'value' ] )
414+ dispatchId : reactorState . get ( 'dispatchId' ) ,
415+ } )
450416}
451417
452418/**
0 commit comments