-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Editor: Cache block meta-sourcing for getBlock selector #12555
Closed
Closed
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** | ||
* Returns a function which caches a computed value on a given object key. Due | ||
* to its caching being achieved by WeakCache, the function must only accept a | ||
* valid WeakMap key as its argument (objects, arrays). The function is only | ||
* passed the key; any other arguments are discarded. | ||
* | ||
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap | ||
* | ||
* @param {Function} getCacheValue Function to compute the cache value. | ||
* | ||
* @return {Function} Function whose computed value is weakly cached. | ||
*/ | ||
function createWeakCache( getCacheValue ) { | ||
const cache = new WeakMap(); | ||
|
||
return ( key ) => { | ||
if ( ! cache.has( key ) ) { | ||
cache.set( key, getCacheValue( key ) ); | ||
} | ||
|
||
return cache.get( key ); | ||
}; | ||
} | ||
|
||
export default createWeakCache; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import createWeakCache from '../create-weak-cache'; | ||
|
||
describe( 'createWeakCache', () => { | ||
const getNumKeys = jest.fn().mockImplementation( ( object ) => Object.keys( object ).length ); | ||
const getNumKeysCached = createWeakCache( getNumKeys ); | ||
|
||
beforeEach( () => { | ||
getNumKeys.mockClear(); | ||
} ); | ||
|
||
it( 'should return the value from the function argument', () => { | ||
const object = { a: 1 }; | ||
|
||
expect( getNumKeysCached( object ) ).toBe( 1 ); | ||
} ); | ||
|
||
it( 'should return the value from cache', () => { | ||
const object = { a: 1 }; | ||
|
||
expect( getNumKeysCached( object ) ).toBe( 1 ); | ||
expect( getNumKeysCached( object ) ).toBe( 1 ); | ||
expect( getNumKeys ).toHaveBeenCalledTimes( 1 ); | ||
} ); | ||
|
||
it( 'should return the value from the function argument on new reference', () => { | ||
expect( getNumKeysCached( { a: 1 } ) ).toBe( 1 ); | ||
expect( getNumKeysCached( { a: 1 } ) ).toBe( 1 ); | ||
expect( getNumKeys ).toHaveBeenCalledTimes( 2 ); | ||
} ); | ||
|
||
it( 'should throw on invalid key argument', () => { | ||
expect( () => getNumKeysCached( undefined ) ).toThrow(); | ||
} ); | ||
|
||
it( 'should discard additional arguments', () => { | ||
expect( createWeakCache( ( a, b ) => b || 'ok' )( {}, 10 ) ).toBe( 'ok' ); | ||
} ); | ||
} ); |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can‘t we just use memoize instead of rolling our own? We already use it elsewhere, e.g. the i18n package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a small but important difference in how this works using
WeakMap
as the cache storage, where normal memoization would hold on to values in memory forever, this would allow garbage collection to occur.For blocks, we'd really only achieve some significant benefit if we expect blocks to be overwritten at any point. Practically speaking this probably wouldn't occur, so we could potentially be fine with a standard memoization, albeit with a very fragile guarantee against memory leaks.
rememo
(createSelector
) has some internal tricks to achieve a similar effect, so there might be some options there, but it'd be quite indirect.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lodash's documentation includes a note about swapping its underlying cache implementation, though as described it appears to apply globally. Each memoized function has its own cache, so I'd wonder if it might be possible to assign to it directly.
https://lodash.com/docs/4.17.11#memoize
Maybe possible?
Looking at the implementation, I think this would work.