Skip to content

Commit

Permalink
Refactor cache usage
Browse files Browse the repository at this point in the history
  • Loading branch information
phpbg committed Aug 14, 2021
1 parent db279b6 commit c18ea40
Showing 1 changed file with 46 additions and 27 deletions.
73 changes: 46 additions & 27 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,35 @@ import {createApp} from '../node_modules/vue/dist/vue.esm-browser.prod.js';
let api = window.muspnpapi;
dayjs.extend(dayjs_plugin_duration);

/**
* Create an object that can be used as a cache and that remain observable
* @param {number} sizeHint Limit to prevent unlimited growth
* @returns {{}}
*/
function createObservableCache(sizeHint = 20) {
const cache = {};
const fifo = [];
const handler = {
get: function(obj, prop) {
return obj[prop];
},
set: function(obj, prop, value) {
obj[prop] = value;
// Always keep track of effective cache use & remove old entries
// This is suboptimal because we will fill the fifo with duplicates, but it should work well enough in most cases
fifo.push(String(prop));
if (fifo.length > sizeHint) {
const removeId = fifo.shift();
if (!fifo.includes(removeId)) {
delete obj[removeId];
}
}
return true;
}
};
return new Proxy(cache, handler);
}

/**
* Convert a duration string to an dayjs duration object.
*
Expand All @@ -27,7 +56,7 @@ window.app = createApp({
showSpinner: true,
error: null,
refreshErrors: 0,
libraryObjectsCache: null,
libraryObjectsCache: createObservableCache(),
selectedItem: [],
playlist: null,
currentPlayingItem: null,
Expand All @@ -41,13 +70,15 @@ window.app = createApp({
currentVolume: null,
searchCapabilities: null,
search: null,
searchResults: null,
searchCache: createObservableCache()
}
},
watch: {
currentMediaServer: function (device) {
this.showSpinner = true;
this.libraryObjectsCache = null;
this.libraryObjectsCache = createObservableCache();
this.search = null;
this.searchCache = createObservableCache()
this.selectedItem = [];
this.searchCapabilities = null;
api.selectServer({usn: device.usn})
Expand Down Expand Up @@ -89,11 +120,14 @@ window.app = createApp({
return;
}
const searchStr = this.searchCapabilities.map(sc => `${sc} contains "${search}"`).join(' or ')
this.searchResults = null;
return api
.search({id: 0, start: 0, count: 0, search: searchStr})
.then(result => this.searchResults = result)
}
.then(result => {
if (result.UpdateID == null || this.searchCache?.[search]?.UpdateID !== result.UpdateID) {
this.searchCache[search] = result;
}
})
},
},
created: function () {
const app = this;
Expand Down Expand Up @@ -172,39 +206,24 @@ window.app = createApp({
return this._currentPosition_currentPosition.format('HH:mm:ss')
},
libraryObjects: function () {
if (this.search && this.searchResults) {
return this.searchResults.Result;
if (this.search) {
return this.searchCache[this.search]?.Result;
}
if (this.currentContainer == null) {
return this.libraryObjectsCache?.data?.[0]?.Result;
return this.libraryObjectsCache?.[0]?.Result;
}
return this.libraryObjectsCache?.data?.[this.currentContainer['@_id']]?.Result
return this.libraryObjectsCache?.[this.currentContainer['@_id']]?.Result
}
},
methods: {
browse: function ({id, start, count}) {
this.showSpinner = true;
return api.browse({id, start, count})
.then(res => {
if (!this.libraryObjectsCache?.data) {
this.libraryObjectsCache = {
data: {},
fifo: [],
}
}
// Update cache if cache miss or UpdateID changed
if (res.UpdateID == null || this.libraryObjectsCache.data?.[id]?.UpdateID !== res.UpdateID) {
if (res.UpdateID == null || this.libraryObjectsCache?.[id]?.UpdateID !== res.UpdateID) {
// Also freeze res because we don't need reactivity on this potentially big structure
this.libraryObjectsCache.data[id] = Object.freeze(res);
}
// Always keep track of effective cache use & remove old entries
// This is suboptimal because we will fill the fifo with duplicates, but it should work well enough in most cases
this.libraryObjectsCache.fifo.push(String(id));
if (this.libraryObjectsCache.fifo.length > 20) {
const removeId = this.libraryObjectsCache.fifo.shift();
if (!this.libraryObjectsCache.fifo.includes(removeId)) {
delete this.libraryObjectsCache.data[removeId]
}
this.libraryObjectsCache[id] = Object.freeze(res);
}
})
.catch(err => this.error = err)
Expand Down

0 comments on commit c18ea40

Please sign in to comment.