I try to store objects in localStorage
but sometimes I run out of space.
When I try to store an object with localStorage
but don't have enough storage - is there a way to simply delete as much local data as needed to free that space, starting the deletion from the oldest elements?
Is there an API in browsers that lets me do that?
The data is not stored and no existing data is overwritten.
localStorage is similar to sessionStorage , except that while localStorage data has no expiration time, sessionStorage data gets cleared when the page session ends — that is, when the page is closed.
It is limited to about 5MB and can contain only strings. LocalStorage is not accessible from web workers or service workers. Cookies have their uses, but should not be used for storage.
Note: Web storage APIs like LocalStorage and SessionStorage remain fixed at 5 MB. Note: Web storage APIs like LocalStorage and SessionStorage remain fixed at 5 MB.
Here is a small proof of concept I just whipped up. It assumes an exception is thrown when you try to store items and have no space.
Code is annotated
var Storage = function (iden) { // a storage wrapper object
var storage; // temp storage with variable
if (localStorage[iden]) { // if we already did this, reuse
storage = JSON.parse(localStorage[iden]);
} else {
// the queue is for the item order to find out oldest
storage = {
__queue: [],
items: {}
};
}
function fetch(key) {
console.log(storage);
return storage.items[key];
}
function put(key, value) {
try {
storage.__queue.push(key);
storage.items[key] = value;
localStorage[iden] = JSON.stringify(storage);
} catch (e) { // out of space
if (storage.__queue.length === 0) throw Exception("Too big anyway");
var k = storage.__queue.pop();
delete storage.items[k];
return put(key, value); //try again after deleting
}
}
return {
put: put,
fetch: fetch
};
};
Inspired by @Benjamin's awesome Proof-Of-Concept i used some of his code to come out with another solution, this function will remove the least used value. For instance you have a value like user_id
you read for this value a lot of times, but if this was added first you will lose it when you run out of space.
So this solution will remove the value depending on how much they were used
var Storage = function (iden) { // a storage wrapper object
var storage; // temp storage with variable
if (localStorage[iden]) { // if we already did this, reuse
storage = JSON.parse(localStorage[iden]);
} else {
// frequency map contains which key was hit how many times.
storage = {
__freq: {},
items: {}
};
}
function fetch(key) {
storage.__freq[key]++;
return storage.items[key];
}
function deleteLeastUsed(){
var min_used = '', min_value = 0;
var keys = Object.keys(storage._freq);
// This will be always the first key..awesome ?
min_used = keys.pop();
min_value = storage.__freq[min_used];
keys.forEach(function(key){
if( min_value > storage.__freq[key] ){
min_used = key;
min_value = storage.__freq[min_used];
}
});
delete storage._freq[min_used]
delete storage.items[min_used];
}
function put(key, value) {
try {
// sets frequency to 0 if the key is over-written
// you can use this as `touch` if you don't wanna use a value more times and wan't to free it just set it to its value
storage.__freq[key] = 0;
storage.items[key] = value;
localStorage[iden] = JSON.stringify(storage);
} catch (e) { // out of space
if ( Object.keys(storage.__freq).length === 0)
throw Exception("Too big anyway");
deleteLeastUsed();
return put(key, value); //try again after deleting
}
}
return {
put: put,
fetch: fetch
};
};
Besides if your data-requirements are really high you might wanna consider switching to IndexedDB instead of localStorage. :-)
I've found this in google: https://github.com/pamelafox/lscache Is a 'memcache' library for localstorage
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With