Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/ember-metal/lib/alias.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
Descriptor,
defineProperty
} from './properties';
import { ComputedProperty } from './computed';
import { ComputedProperty, getCacheFor } from './computed';
import { meta as metaFor } from './meta';
import {
addDependentKeys,
Expand Down Expand Up @@ -52,9 +52,9 @@ export class AliasedProperty extends Descriptor {
get(obj, keyName) {
let ret = get(obj, this.altKey);
let meta = metaFor(obj);
let cache = meta.writableCache();
if (cache[keyName] !== CONSUMED) {
cache[keyName] = CONSUMED;
let cache = getCacheFor(obj);
if (cache.get(keyName) !== CONSUMED) {
cache.set(keyName, CONSUMED);
addDependentKeys(this, obj, keyName, meta);
}
return ret;
Expand Down
7 changes: 2 additions & 5 deletions packages/ember-metal/lib/chains.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { get } from './property_get';
import { descriptorFor, meta as metaFor, peekMeta } from './meta';
import { watchKey, unwatchKey } from './watch_key';
import { cacheFor } from './computed';
import { getCachedValueFor } from './computed';
import { eachProxyFor } from './each_proxy';

const FIRST_KEY = /^([^\.]+)/;
Expand Down Expand Up @@ -333,10 +333,7 @@ function lazyGet(obj, key) {
return get(obj, key);
// Otherwise attempt to get the cached value of the computed property
} else {
let cache = meta.readableCache();
if (cache !== undefined) {
return cacheFor.get(cache, key);
}
return getCachedValueFor(obj, key);
}
}

Expand Down
85 changes: 32 additions & 53 deletions packages/ember-metal/lib/computed.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { inspect } from 'ember-utils';
import { assert, warn, Error as EmberError } from 'ember-debug';
import { set } from './property_set';
import { meta as metaFor, peekMeta, UNDEFINED } from './meta';
import { meta as metaFor, peekMeta } from './meta';
import expandProperties from './expand_properties';
import {
Descriptor,
Expand Down Expand Up @@ -317,9 +317,8 @@ ComputedPropertyPrototype.didChange = function(obj, keyName) {
return;
}

let cache = meta.readableCache();
if (cache !== undefined && cache[keyName] !== undefined) {
cache[keyName] = undefined;
let cache = peekCacheFor(obj);
if (cache !== undefined && cache.delete(keyName)) {
removeDependentKeys(this, obj, keyName, meta);
}
};
Expand All @@ -329,20 +328,17 @@ ComputedPropertyPrototype.get = function(obj, keyName) {
return this._getter.call(obj, keyName);
}

let meta = metaFor(obj);
let cache = meta.writableCache();
let cache = getCacheFor(obj);

let result = cache[keyName];
if (result === UNDEFINED) {
return undefined;
} else if (result !== undefined) {
return result;
if (cache.has(keyName)) {
return cache.get(keyName);
}

let ret = this._getter.call(obj, keyName);

cache[keyName] = ret === undefined ? UNDEFINED : ret;
cache.set(keyName, ret);

let meta = metaFor(obj);
let chainWatchers = meta.readableChainWatchers();
if (chainWatchers !== undefined) {
chainWatchers.revalidate(keyName);
Expand Down Expand Up @@ -373,7 +369,7 @@ ComputedPropertyPrototype._throwReadOnlyError = function computedPropertyThrowRe
};

ComputedPropertyPrototype.clobberSet = function computedPropertyClobberSet(obj, keyName, value) {
let cachedValue = cacheFor(obj, keyName);
let cachedValue = getCachedValueFor(obj, keyName);
defineProperty(obj, keyName, null, cachedValue);
set(obj, keyName, value);
return value;
Expand All @@ -395,15 +391,9 @@ ComputedPropertyPrototype.setWithSuspend = function computedPropertySetWithSuspe

ComputedPropertyPrototype._set = function computedPropertySet(obj, keyName, value) {
let meta = metaFor(obj);
let cache = meta.writableCache();

let val = cache[keyName];
let hadCachedValue = val !== undefined;

let cachedValue;
if (hadCachedValue && val !== UNDEFINED) {
cachedValue = val;
}
let cache = getCacheFor(obj);
let hadCachedValue = cache.has(keyName);
let cachedValue = cache.get(keyName);

let ret = this._setter.call(obj, keyName, value, cachedValue);

Expand All @@ -416,7 +406,7 @@ ComputedPropertyPrototype._set = function computedPropertySet(obj, keyName, valu
addDependentKeys(this, obj, keyName, meta);
}

cache[keyName] = ret === undefined ? UNDEFINED : ret;
cache.set(keyName, ret);

notifyPropertyChange(obj, keyName, meta);

Expand All @@ -428,10 +418,9 @@ ComputedPropertyPrototype.teardown = function(obj, keyName, meta) {
if (this._volatile) {
return;
}
let cache = meta.readableCache();
if (cache !== undefined && cache[keyName] !== undefined) {
let cache = peekCacheFor(obj);
if (cache !== undefined && cache.delete(keyName)) {
removeDependentKeys(this, obj, keyName, meta);
cache[keyName] = undefined;
}
};

Expand Down Expand Up @@ -535,6 +524,8 @@ export default function computed(...args) {
return cp;
}

const COMPUTED_PROPERTY_CACHED_VALUES = new WeakMap();

/**
Returns the cached value for a property, if one exists.
This can be useful for peeking at the value of a computed
Expand All @@ -550,39 +541,27 @@ export default function computed(...args) {
@return {Object} the cached value
@public
*/
function cacheFor(obj, key) {
let meta = peekMeta(obj);
let cache = meta !== undefined ? meta.source === obj && meta.readableCache() : undefined;
let ret = cache !== undefined ? cache[key] : undefined;

if (ret === UNDEFINED) {
return undefined;
export function getCacheFor(obj) {
let cache = COMPUTED_PROPERTY_CACHED_VALUES.get(obj);
if (cache === undefined) {
cache = new Map();
COMPUTED_PROPERTY_CACHED_VALUES.set(obj, cache);
}
return ret;
return cache;
}

cacheFor.set = function(cache, key, value) {
if (value === undefined) {
cache[key] = UNDEFINED;
} else {
cache[key] = value;
export function getCachedValueFor(obj, key) {
let cache = COMPUTED_PROPERTY_CACHED_VALUES.get(obj);
if (cache !== undefined) {
return cache.get(key);
}
};

cacheFor.get = function(cache, key) {
let ret = cache[key];
if (ret === UNDEFINED) {
return undefined;
}
return ret;
};
}

cacheFor.remove = function(cache, key) {
cache[key] = undefined;
};
export function peekCacheFor(obj) {
return COMPUTED_PROPERTY_CACHED_VALUES.get(obj);
}

export {
ComputedProperty,
computed,
cacheFor
computed
};
4 changes: 3 additions & 1 deletion packages/ember-metal/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
export { default } from './core'; // reexports
export {
default as computed,
cacheFor,
getCacheFor,
getCachedValueFor,
peekCacheFor,
ComputedProperty
} from './computed';
export { default as alias } from './alias';
Expand Down
5 changes: 0 additions & 5 deletions packages/ember-metal/lib/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ export class Meta {
counters.metaInstantiated++;
}

this._cache = undefined;

if (EMBER_METAL_ES5_GETTERS) {
this._descriptors = undefined;
}
Expand Down Expand Up @@ -266,9 +264,6 @@ export class Meta {
}
}

writableCache() { return this._getOrCreateOwnMap('_cache'); }
readableCache() { return this._cache; }

writableTags() { return this._getOrCreateOwnMap('_tags'); }
readableTags() { return this._tags; }

Expand Down
7 changes: 4 additions & 3 deletions packages/ember-metal/lib/properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { HAS_NATIVE_PROXY } from 'ember-utils';
import { descriptorFor, meta as metaFor, peekMeta, DESCRIPTOR, UNDEFINED } from './meta';
import { overrideChains } from './property_events';
import { DESCRIPTOR_TRAP, EMBER_METAL_ES5_GETTERS, MANDATORY_SETTER } from 'ember/features';
import { peekCacheFor } from './computed';
// ..........................................................
// DESCRIPTOR
//
Expand Down Expand Up @@ -338,9 +339,9 @@ export function _hasCachedComputedProperties() {

function didDefineComputedProperty(constructor) {
if (hasCachedComputedProperties === false) { return; }
let cache = metaFor(constructor).readableCache();

if (cache && cache._computedProperties !== undefined) {
cache._computedProperties = undefined;
let cache = peekCacheFor(constructor);
if (cache !== undefined) {
cache.delete('_computedProperties');
}
}
14 changes: 7 additions & 7 deletions packages/ember-metal/tests/computed_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { testBoth } from 'internal-test-helpers';
import {
ComputedProperty,
computed,
cacheFor,
getCachedValueFor,
Descriptor,
defineProperty,
get,
Expand Down Expand Up @@ -316,24 +316,24 @@ testBoth('inherited property should not pick up cache', function(get, set, asser
assert.equal(get(objB, 'foo'), 'bar 2', 'objB third get');
});

testBoth('cacheFor should return the cached value', function(get, set, assert) {
assert.equal(cacheFor(obj, 'foo'), undefined, 'should not yet be a cached value');
testBoth('getCachedValueFor should return the cached value', function(get, set, assert) {
assert.equal(getCachedValueFor(obj, 'foo'), undefined, 'should not yet be a cached value');

get(obj, 'foo');

assert.equal(cacheFor(obj, 'foo'), 'bar 1', 'should retrieve cached value');
assert.equal(getCachedValueFor(obj, 'foo'), 'bar 1', 'should retrieve cached value');
});

testBoth('cacheFor should return falsy cached values', function(get, set, assert) {
testBoth('getCachedValueFor should return falsy cached values', function(get, set, assert) {
defineProperty(obj, 'falsy', computed(function() {
return false;
}));

assert.equal(cacheFor(obj, 'falsy'), undefined, 'should not yet be a cached value');
assert.equal(getCachedValueFor(obj, 'falsy'), undefined, 'should not yet be a cached value');

get(obj, 'falsy');

assert.equal(cacheFor(obj, 'falsy'), false, 'should retrieve cached value');
assert.equal(getCachedValueFor(obj, 'falsy'), false, 'should retrieve cached value');
});

testBoth('setting a cached computed property passes the old value as the third argument', function(get, set, assert) {
Expand Down
4 changes: 2 additions & 2 deletions packages/ember-metal/tests/observer_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
notifyPropertyChange,
defineProperty,
computed,
cacheFor,
getCachedValueFor,
Mixin,
mixin,
observer,
Expand Down Expand Up @@ -484,7 +484,7 @@ testBoth('depending on a chain with a computed property', function(get, set, ass
changed++;
});

assert.equal(cacheFor(obj, 'computed'), undefined, 'addObserver should not compute CP');
assert.equal(getCachedValueFor(obj, 'computed'), undefined, 'addObserver should not compute CP');

set(obj, 'computed.foo', 'baz');

Expand Down
11 changes: 6 additions & 5 deletions packages/ember-runtime/lib/mixins/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {
eachProxyArrayWillChange,
eachProxyArrayDidChange,
beginPropertyChanges,
endPropertyChanges
endPropertyChanges,
peekCacheFor
} from 'ember-metal';
import { assert, deprecate } from 'ember-debug';
import Enumerable from './enumerable';
Expand Down Expand Up @@ -105,7 +106,7 @@ export function arrayContentDidChange(array, startIdx, removeAmt, addAmt) {
sendEvent(array, '@array:change', [array, startIdx, removeAmt, addAmt]);

let meta = peekMeta(array);
let cache = meta !== undefined ? meta.readableCache() : undefined;
let cache = peekCacheFor(array);
if (cache !== undefined) {
let length = get(array, 'length');
let addedAmount = (addAmt === -1 ? 0 : addAmt);
Expand All @@ -114,17 +115,17 @@ export function arrayContentDidChange(array, startIdx, removeAmt, addAmt) {
let previousLength = length - delta;

let normalStartIdx = startIdx < 0 ? previousLength + startIdx : startIdx;
if (cache.firstObject !== undefined && normalStartIdx === 0) {
if (cache.has('firstObject') && normalStartIdx === 0) {
notifyPropertyChange(array, 'firstObject', meta);
}

if (cache.lastObject !== undefined) {
if (cache.has('lastObject')) {
let previousLastIndex = previousLength - 1;
let lastAffectedIndex = normalStartIdx + removedAmount;
if (previousLastIndex < lastAffectedIndex) {
notifyPropertyChange(array, 'lastObject', meta);
}
}
}
}

return array;
Expand Down
4 changes: 2 additions & 2 deletions packages/ember-runtime/lib/mixins/observable.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
endPropertyChanges,
addObserver,
removeObserver,
cacheFor,
getCachedValueFor,
isNone
} from 'ember-metal';
import { assert } from 'ember-debug';
Expand Down Expand Up @@ -476,6 +476,6 @@ export default Mixin.create({
@public
*/
cacheFor(keyName) {
return cacheFor(this, keyName);
return getCachedValueFor(this, keyName);
},
});
2 changes: 1 addition & 1 deletion packages/ember/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const computed = metal.computed;
computed.alias = metal.alias;
Ember.computed = computed;
Ember.ComputedProperty = metal.ComputedProperty;
Ember.cacheFor = metal.cacheFor;
Ember.cacheFor = metal.getCachedValueFor;

Ember.assert = EmberDebug.assert;
Ember.warn = EmberDebug.warn;
Expand Down
2 changes: 1 addition & 1 deletion packages/ember/tests/reexports_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ let allExports =[
['computed', 'ember-metal'],
['computed.alias', 'ember-metal', 'alias'],
['ComputedProperty', 'ember-metal'],
['cacheFor', 'ember-metal'],
['cacheFor', 'ember-metal', 'getCachedValueFor'],
['merge', 'ember-metal'],
['instrument', 'ember-metal'],
['Instrumentation.instrument', 'ember-metal', 'instrument'],
Expand Down