Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

localStorage, limits and data expiration when limits are reached

Tags:

javascript

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?

like image 433
cedivad Avatar asked Nov 18 '13 19:11

cedivad


People also ask

What happens if LocalStorage is full?

The data is not stored and no existing data is overwritten.

Does local storage ever expire?

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.

Is there a limit to LocalStorage?

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.

What is the limit of data size LocalStorage in Google Chrome?

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.


3 Answers

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
    };
};
like image 50
Benjamin Gruenbaum Avatar answered Nov 20 '22 17:11

Benjamin Gruenbaum


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. :-)

like image 20
ShrekOverflow Avatar answered Nov 20 '22 17:11

ShrekOverflow


I've found this in google: https://github.com/pamelafox/lscache Is a 'memcache' library for localstorage

like image 20
Aguardientico Avatar answered Nov 20 '22 17:11

Aguardientico