Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why use 2 keys for 1 value? #79

Open
peter-gribanov opened this issue Jan 10, 2018 · 8 comments
Open

Why use 2 keys for 1 value? #79

peter-gribanov opened this issue Jan 10, 2018 · 8 comments

Comments

@peter-gribanov
Copy link
Contributor

peter-gribanov commented Jan 10, 2018

Why use 2 keys?

  1. key for store the value
  2. key for store the expiration time

Why don't use the structure?

{
    value: my_value,
    expire: timestamp,
}

I see several problems using two keys:

1. Nullable values #52

If you use a structure, you can know for sure that the value is in the cache even if it's empty.

2. Integrity of keys

One of the keys can be lost and the integrity of the data will be broken.
The browser sometimes cleans localStorage.
localStorage can be cleared by the user.

3. Speed of work

In the get() method, you twice access to the localStorage.
I don't think that this has a positive effect on performance.

4. More space is required

Two keys take up more space than the structure.

For example:

lscache.set('greeting', 'Hello World!', 2);

This code makes two kays:

key value
lscache-greeting Hello World!
lscache-greeting-cacheexpiration 25259579612566

That is ~74 bytes.

If you use a structure, you get:

key value
lscache-greeting {value:'Hello World!',expire:25259579612566}

That is ~60 bytes.

If you use a bucket, the difference will be even greater.

lscache.setBucket('AcmeDemo-');
lscache.set('greeting', 'Hello World!', 2);
key value
lscache-AcmeDemo-greeting Hello World!
lscache-AcmeDemo-greeting-cacheexpiration 25259579612566
key value
lscache-AcmeDemo-greeting {value:'Hello World!',expire:25259579612566}

~92 bytes vs ~69 bytes

This difference can be further reduced if you change the storage structure to array:

[my_value, timestamp]
key value
lscache-AcmeDemo-greeting ['Hello World!',25259579612566]

~92 bytes vs ~56 bytes

This is almost a twofold saving.
For someone, this can be meaningful.

In sum

Maybe i don't understand something, please explain.

PS: I can make PR for fix it.

@pamelafox
Copy link
Owner

Hm. Great points on the PROs, better performance and space. At this point, I can't recall why I went with 2 keys. I'd be a bit concerned about changing the underlying implementation in case of folks somehow relying on the 2-key storage. As I mentioned in another thread, I tend to be very cautious with PRs, since I'm not a current user myself and just maintain this in free time. I'd hate to introduce any breaking changes.

@cantsdmr
Copy link

lscache maybe should reach to 2.0 with these features without any breaking changes.

@peter-gribanov
Copy link
Contributor Author

@cantsdmr need active support of the project in order to make a new major release. Pamela can't deal with the project.

I could admin project, but i still have a little experience with using this library.

@cantsdmr
Copy link

@peter-gribanov yes, I think you can manage a fork of lscache or 2.0 release.

@rcky
Copy link

rcky commented Jan 12, 2018

@pamelafox @peter-gribanov I guess you wanted to prevent the cache from parsing the content at the specified key just to read the expiration time (which I think is relevant for large datasets).

@peter-gribanov
Copy link
Contributor Author

peter-gribanov commented Jan 12, 2018

@rcky We need to read the expiration time separately from the data only when the cache is out of date.

If we read data from the cache more often than flush it (must be), then it's more efficient to read the expiration time together with the data and not do unnecessary actions.

For optimization, we can opt out of JSON:

25259579612566|Hello World!

In order to know the expiration time, it is enough to read just a few first bytes and no longer spend time analyzing JSON.

@rcky
Copy link

rcky commented Jan 12, 2018

@peter-gribanov I actually stumbled upon this discussion by chance. I don't doubt your argumentation, it just seemed to be the reasoning behind the current implementation.

But just out of curiosity:

We need to read the expiration time separately from the data only when the cache is out of date.

How do you know the cache is out of date without reading the expiration time (yeah reading it partially upfront seems legit)?

@peter-gribanov
Copy link
Contributor Author

peter-gribanov commented Jan 12, 2018

How do you know the cache is out of date without reading the expiration time? (yeah reading it partially upfront seems legit)?

@rcky i say

We need to read the expiration time separately from the data only when the cache is out of date.

We always need to read the expiration time, but don't always need to read the data.
But, there are far fewer cases when we need to read the time without reading the data, so it's more economical to store them together.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants