@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 5.51 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import t from"./PooledArray.js";const e=-3,i=e-1;var s;!function(t){t[t.ALL=0]="ALL",t[t.SOME=1]="SOME"}(s||(s={}));class r{constructor(t,e,i,s=0){this.name=t,this._storage=e,this._defaultPriority=s,this.id=o+++":",this.size=0,this.maxSize=-1,this._removeFunc=!1,this._hit=0,this._miss=0,this._storage.register(this),i&&(this._storage.registerRemoveFunc(this.id,i),this._removeFunc=!0)}destroy(){this._storage.clear(this),this._removeFunc&&this._storage.deregisterRemoveFunc(this.id),this._storage.deregister(this),this._storage=null}get hitRate(){return this._hit/(this._hit+this._miss)}get storageSize(){return this._storage.size}getSize(t){return this._storage.getSize(this,t)}resetHitRate(){this._hit=this._miss=0}put(t,e,i=this._defaultPriority){this._storage.put(this,t,e,e.cachedMemory,i)}pop(t){const e=this._storage.pop(this,t);return void 0===e?++this._miss:++this._hit,e}get(t){const e=this._storage.get(this,t);return void 0===e?++this._miss:++this._hit,e}peek(t){return this._storage.peek(this,t)}updateSize(t,e){this._storage.updateSize(this,t,e,e.cachedMemory)}clear(){this._storage.clear(this)}clearAll(){this._storage.clearAll()}get performanceInfo(){return this._storage.performanceInfo}resetStats(){this._storage.resetStats()}}class h{get size(){return this._size}constructor(e=10485760){this._maxSize=e,this._db=new Map,this._size=0,this._hit=0,this._miss=0,this._removeFuncs=new t,this._users=new t}destroy(){this.clearAll(),this._removeFuncs.clear(),this._users.clear()}register(t){this._users.push(t)}deregister(t){this._users.removeUnordered(t)}registerRemoveFunc(t,e){this._removeFuncs.push([t,e])}deregisterRemoveFunc(t){this._removeFuncs.filterInPlace((e=>e[0]!==t))}get maxSize(){return this._maxSize}set maxSize(t){this._maxSize=Math.max(t,-1),this._checkSize()}getSize(t,e){const i=this._db.get(t.id+e);return i?.size??0}put(t,r,h,o,_){r=t.id+r;const a=this._db.get(r);if(a&&(this._size-=a.size,t.size-=a.size,this._db.delete(r),a.entry!==h&&this._notifyRemove(r,a.entry,a.size,s.ALL)),o>this._maxSize)return void this._notifyRemove(r,h,o,s.ALL);if(void 0===h)return void console.warn("Refusing to cache undefined entry ");if(!o||o<0)return console.warn(`Refusing to cache entry with size ${o} for key ${r}`),void this._notifyRemove(r,h,0,s.ALL);const c=1+Math.max(_,i)-e;this._db.set(r,new n(h,o,c)),this._size+=o,t.size+=o,this._checkSize()}updateSize(t,e,i,r){e=t.id+e;const h=this._db.get(e);if(h&&h.entry===i){for(this._size-=h.size,t.size-=h.size;r>this._maxSize;){const t=this._notifyRemove(e,i,r,s.SOME);if(!(null!=t&&t>0))return void this._db.delete(e);r=t}h.size=r,this._size+=r,t.size+=r,this._checkSize()}}pop(t,e){e=t.id+e;const i=this._db.get(e);if(i)return this._size-=i.size,t.size-=i.size,this._db.delete(e),++this._hit,i.entry;++this._miss}get(t,e){e=t.id+e;const i=this._db.get(e);if(void 0!==i)return this._db.delete(e),i.lives=i.lifetime,this._db.set(e,i),++this._hit,i.entry;++this._miss}peek(t,e){const i=this._db.get(t.id+e);return i?++this._hit:++this._miss,i?.entry}get performanceInfo(){const t={Size:Math.round(this._size/1048576)+"/"+Math.round(this._maxSize/1048576)+"MB","Hit rate":Math.round(100*this._getHitRate())+"%",Entries:this._db.size.toString()},i={},s=new Array;this._db.forEach(((t,e)=>{const r=t.lifetime;s[r]=(s[r]||0)+t.size,this._users.forAll((s=>{const{id:r,name:h}=s;if(e.startsWith(r)){const e=i[h]||0;i[h]=e+t.size}}))}));const r={};this._users.forAll((t=>{const e=t.name;if("hitRate"in t&&"number"==typeof t.hitRate&&!isNaN(t.hitRate)&&t.hitRate>0){const s=i[e]||0;i[e]=s,r[e]=Math.round(100*t.hitRate)+"%"}else r[e]="0%"}));const h=Object.keys(i);h.sort(((t,e)=>i[e]-i[t])),h.forEach((e=>t[e]=Math.round(i[e]/2**20)+"MB / "+r[e]));for(let o=s.length-1;o>=0;--o){const i=s[o];i&&(t["Priority "+(o+e-1)]=Math.round(i/this._size*100)+"%")}return t}resetStats(){this._hit=this._miss=0,this._users.forAll((t=>t.resetHitRate()))}clear(t){const e=t.id;this._db.forEach(((t,i)=>{i.startsWith(e)&&(this._size-=t.size,this._db.delete(i),this._notifyRemove(i,t.entry,t.size,s.ALL))})),t.size=0}clearAll(){this._db.forEach(((t,e)=>this._notifyRemove(e,t.entry,t.size,s.ALL))),this._users.forAll((t=>t.size=0)),this._size=0,this._db.clear()}_getHitRate(){return this._hit/(this._hit+this._miss)}_notifyRemove(t,e,i,s){let r;return this._removeFuncs.some((h=>{if(t.startsWith(h[0])){const t=h[1](e,s,i);return"number"==typeof t&&(r=t),!0}return!1})),r}_checkSize(){this._users.forAll((t=>this._checkSizeLimits(t))),this._checkSizeLimits()}_checkSizeLimits(t){const e=t??this;if(e.maxSize<0||e.size<=e.maxSize)return;const i=t?.id;let s=!0;for(;s;){s=!1;for(const[r,h]of this._db)if(0===h.lifetime&&(!i||r.startsWith(i))){if(this._purgeItem(r,h,t),e.size<=.9*e.maxSize)return;s||=this._db.has(r)}}for(const[r,h]of this._db)if((!i||r.startsWith(i))&&(this._purgeItem(r,h,t),e.size<=.9*e.maxSize))return}_purgeItem(t,e,i=this._users.find((e=>t.startsWith(e.id)))){if(this._db.delete(t),e.lives<=1){this._size-=e.size,i&&(i.size-=e.size);const r=this._notifyRemove(t,e.entry,e.size,s.SOME);null!=r&&r>0&&(this._size+=r,i&&(i.size+=r),e.lives=e.lifetime,e.size=r,this._db.set(t,e))}else--e.lives,this._db.set(t,e)}}let o=0;class n{constructor(t,e,i){this.entry=t,this.size=e,this.lifetime=i,this.lives=i}}export{r as MemCache,h as MemCacheStorage,e as MinPriority,i as NoPriority,s as RemoveMode};