jaan
jaan

Reputation: 143

How to store and optimize large values in cookies

I need to store the user preferences in a cookie.

If I store all the unique (8 characters) values in a cookie, then it will get overloaded. I need a mechanism to do some mapping so that minimal value is stored in cookie.

My requirement matches this question, but only difference is that I have large data set (100 items per select column).

Upvotes: 2

Views: 2692

Answers (3)

R. Hill
R. Hill

Reputation: 3620

That's a good question. Given your requirements, I don't see much choices left on how to proceed. As ThatBlairGuy suggested, a bit map seems to be the way to go. Your 300 choices translate to 300 bits. Now I personally would stick to use only 6 bits per byte, to make a quick and easy translation to base64, for storage purpose. 300 / 6 = 50 characters for the values coming from the drop-down.

The value of any preference has to be hardcoded for good though, you can't remove or add any in the middle: Any new preference will have to be added at the end of the bit map, or use a bit that is no longer used somewhere in the map.

Edit: Given the comments re. bit map, I will flesh out what I had in mind for the implementation. Assuming a bit, each corresponding to a off-on switch of a particular option (an entry in the drop-box):

this.bitmap = [];
this.customBase64code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-";
...
// index=index of bit within bit map, on=state of the bit
this.setOption=function(index,on) {
    var islot = Math.floor(index / 6);
    var ibit = index % 6;
    if ( this.bitmap[islot] === undefined ) {
        while ( this.bitmap.length <= islot ) {
            this.bitmap.push(0);
        }
    }
    if (on) {
        this.bitmap[islot] |= (1 << ibit);
    }
    else {
        this.bitmap[islot] &= ~(1 << ibit);
    }
};
this.getOption=function(index) {
    var islot = Math.floor(index / 6);
    if ( this.bitmap[islot] === undefined ) {
        return 0;
        }
    return this.bitmap[islot] & (1 << (index % 6));
};
this.getStringFromOptions=function() {
    var bitmap64 = [];
    var encoder64 = customBase64code.split('');
    var n = this.bitmap.length;
    for ( var i = 0; i < n; i++ ) {
        bitmap64.push(encoder64[this.bitmap[i]]);
    }
    return bitmap64.join('');
};
this.getOptionsFromString=function(s) {
    var bitmap64 = s.split('');
    var decoder64 = this.customBase64code;
    var n = bitmap64.length;
    for ( var i = 0; i < n; i++ ) {
        this.bitmap.push(decoder64.indexOf(bitmap64[i]));
    }
};

Disclaimer: I didn't test any of the above.

Upvotes: 2

ThatBlairGuy
ThatBlairGuy

Reputation: 2462

Two possibilities:

A) Make your values numeric and powers of 2 (1,2,4,8,16,etc) and store a single value in the cookie as a bitmap. (Or in the server-side code, map the distinct values to powers of 2.)

B) Store the values in the cookie as a delimited list.

Updated: 6:40PM

Seeing that you have the possibility of a large number of selections, neither of my original solutions is going to work. To deal with that large an amount of data, I think you're going to need to create a "session id" of some sort, save the actual settings in a database or other persistent storage, and store the session id in the cookie.

(You'll of course want to make the cookie only persist for the duration of the browser session and delete the stored settings after you can be reasonably certain the browser session has ended -- perhaps a week or so.)

Upvotes: 3

Niels van der Rest
Niels van der Rest

Reputation: 32184

You can store the indexes of the selected items. For example, if the user has selected item 1 and 3 from list A, item 4 from list B and the first 10 items of list C, you'd get something like this:

A[0,2],B[3],C[0-9]

You'd have to write some simple parsing code to read out the values though.

In the worst case scenario, when the user has selected all the odd or even items, you'll need about 150 characters for a list containing a total of 100 items. If the user has selected all 100 items, you'll only need A[0-99].

Upvotes: 1

Related Questions