fix(view_factory): fix caching of views
Previous implementation had bugs, and did not cache per ProtoView.
This commit is contained in:
4
modules/angular2/src/core/application.js
vendored
4
modules/angular2/src/core/application.js
vendored
@ -96,7 +96,7 @@ function _injectorBindings(appComponentType): List<Binding> {
|
||||
(capacity, eventManager, shadowDomStrategy) => new rvf.ViewFactory(capacity, eventManager, shadowDomStrategy),
|
||||
[rvf.VIEW_POOL_CAPACITY, EventManager, ShadowDomStrategy]
|
||||
),
|
||||
bind(rvf.VIEW_POOL_CAPACITY).toValue(100000),
|
||||
bind(rvf.VIEW_POOL_CAPACITY).toValue(10000),
|
||||
ProtoViewFactory,
|
||||
// TODO(tbosch): We need an explicit factory here, as
|
||||
// we are getting errors in dart2js with mirrors...
|
||||
@ -104,7 +104,7 @@ function _injectorBindings(appComponentType): List<Binding> {
|
||||
(capacity) => new ViewFactory(capacity),
|
||||
[VIEW_POOL_CAPACITY]
|
||||
),
|
||||
bind(VIEW_POOL_CAPACITY).toValue(100000),
|
||||
bind(VIEW_POOL_CAPACITY).toValue(10000),
|
||||
Compiler,
|
||||
CompilerCache,
|
||||
TemplateResolver,
|
||||
|
@ -12,37 +12,38 @@ export const VIEW_POOL_CAPACITY = 'ViewFactory.viewPoolCapacity';
|
||||
|
||||
@Injectable()
|
||||
export class ViewFactory {
|
||||
_poolCapacity:number;
|
||||
_pooledViews:List<viewModule.AppView>;
|
||||
_poolCapacityPerProtoView:number;
|
||||
_pooledViewsPerProtoView:Map<vieModule.ProtoView, List<viewModule.AppView>>;
|
||||
|
||||
constructor(@Inject(VIEW_POOL_CAPACITY) capacity) {
|
||||
this._poolCapacity = capacity;
|
||||
this._pooledViews = ListWrapper.create();
|
||||
constructor(@Inject(VIEW_POOL_CAPACITY) poolCapacityPerProtoView) {
|
||||
this._poolCapacityPerProtoView = poolCapacityPerProtoView;
|
||||
this._pooledViewsPerProtoView = MapWrapper.create();
|
||||
}
|
||||
|
||||
getView(protoView:viewModule.AppProtoView):viewModule.AppView {
|
||||
// TODO(tbosch): benchmark this scanning of views and maybe
|
||||
// replace it with a fancy LRU Map/List combination...
|
||||
var view;
|
||||
for (var i=this._pooledViews.length-1; i>=0; i--) {
|
||||
var pooledView = this._pooledViews[i];
|
||||
if (pooledView.proto === protoView) {
|
||||
view = ListWrapper.removeAt(this._pooledViews, i);
|
||||
var pooledViews = MapWrapper.get(this._pooledViewsPerProtoView, protoView);
|
||||
if (isPresent(pooledViews)) {
|
||||
var result = ListWrapper.removeLast(pooledViews);
|
||||
if (pooledViews.length === 0) {
|
||||
MapWrapper.delete(this._pooledViewsPerProtoView, protoView);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (isBlank(view)) {
|
||||
view = this._createView(protoView);
|
||||
}
|
||||
return view;
|
||||
return this._createView(protoView);
|
||||
}
|
||||
|
||||
returnView(view:viewModule.AppView) {
|
||||
if (view.hydrated()) {
|
||||
throw new BaseException('Only dehydrated Views can be put back into the pool!');
|
||||
}
|
||||
ListWrapper.push(this._pooledViews, view);
|
||||
while (this._pooledViews.length > this._poolCapacity) {
|
||||
ListWrapper.removeAt(this._pooledViews, 0);
|
||||
var protoView = view.proto;
|
||||
var pooledViews = MapWrapper.get(this._pooledViewsPerProtoView, protoView);
|
||||
if (isBlank(pooledViews)) {
|
||||
pooledViews = [];
|
||||
MapWrapper.set(this._pooledViewsPerProtoView, protoView, pooledViews);
|
||||
}
|
||||
if (pooledViews.length < this._poolCapacityPerProtoView) {
|
||||
ListWrapper.push(pooledViews, view);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,41 +18,43 @@ export const VIEW_POOL_CAPACITY = 'render.ViewFactory.viewPoolCapacity';
|
||||
|
||||
@Injectable()
|
||||
export class ViewFactory {
|
||||
_poolCapacity:number;
|
||||
_pooledViews:List<viewModule.RenderView>;
|
||||
_poolCapacityPerProtoView:number;
|
||||
_pooledViewsPerProtoView:Map<pvModule.RenderProtoView, List<viewModule.RenderView>>;
|
||||
_eventManager:EventManager;
|
||||
_shadowDomStrategy:ShadowDomStrategy;
|
||||
|
||||
constructor(@Inject(VIEW_POOL_CAPACITY) capacity, eventManager:EventManager, shadowDomStrategy:ShadowDomStrategy) {
|
||||
this._poolCapacity = capacity;
|
||||
this._pooledViews = ListWrapper.create();
|
||||
constructor(@Inject(VIEW_POOL_CAPACITY) poolCapacityPerProtoView,
|
||||
eventManager:EventManager, shadowDomStrategy:ShadowDomStrategy) {
|
||||
this._poolCapacityPerProtoView = poolCapacityPerProtoView;
|
||||
this._pooledViewsPerProtoView = MapWrapper.create();
|
||||
this._eventManager = eventManager;
|
||||
this._shadowDomStrategy = shadowDomStrategy;
|
||||
}
|
||||
|
||||
getView(protoView:pvModule.RenderProtoView):viewModule.RenderView {
|
||||
// TODO(tbosch): benchmark this scanning of views and maybe
|
||||
// replace it with a fancy LRU Map/List combination...
|
||||
var view;
|
||||
for (var i=this._pooledViews.length-1; i>=0; i--) {
|
||||
var pooledView = this._pooledViews[i];
|
||||
if (pooledView.proto === protoView) {
|
||||
view = ListWrapper.removeAt(this._pooledViews, i);
|
||||
var pooledViews = MapWrapper.get(this._pooledViewsPerProtoView, protoView);
|
||||
if (isPresent(pooledViews)) {
|
||||
var result = ListWrapper.removeLast(pooledViews);
|
||||
if (pooledViews.length === 0) {
|
||||
MapWrapper.delete(this._pooledViewsPerProtoView, protoView);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (isBlank(view)) {
|
||||
view = this._createView(protoView);
|
||||
}
|
||||
return view;
|
||||
return this._createView(protoView);
|
||||
}
|
||||
|
||||
returnView(view:viewModule.RenderView) {
|
||||
if (view.hydrated()) {
|
||||
view.dehydrate();
|
||||
}
|
||||
ListWrapper.push(this._pooledViews, view);
|
||||
while (this._pooledViews.length > this._poolCapacity) {
|
||||
ListWrapper.removeAt(this._pooledViews, 0);
|
||||
var protoView = view.proto;
|
||||
var pooledViews = MapWrapper.get(this._pooledViewsPerProtoView, protoView);
|
||||
if (isBlank(pooledViews)) {
|
||||
pooledViews = [];
|
||||
MapWrapper.set(this._pooledViewsPerProtoView, protoView, pooledViews);
|
||||
}
|
||||
if (pooledViews.length < this._poolCapacityPerProtoView) {
|
||||
ListWrapper.push(pooledViews, view);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user