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

Flake evaluation cache #2930

Merged
merged 2 commits into from Jun 11, 2019
Merged

Flake evaluation cache #2930

merged 2 commits into from Jun 11, 2019

Conversation

edolstra
Copy link
Member

@edolstra edolstra commented Jun 7, 2019

This exploits the hermetic nature of flake evaluation to speed up repeated evaluations of a flake output attribute.

For example (doing nix build on an already present package):

$ time nix build nixpkgs:firefox

real    0m1.497s
user    0m1.160s
sys     0m0.139s

$ time nix build nixpkgs:firefox

real    0m0.052s
user    0m0.038s
sys     0m0.007s

The cache is ~/.cache/nix/eval-cache-v1.sqlite, which has entries like

INSERT INTO Attributes VALUES(
  X'92a907d4efe933af2a46959b082cdff176aa5bfeb47a98fabd234809a67ab195',
  'packages.firefox',
  1,
  '/nix/store/pbalzf8x19hckr8cwdv62rd6g0lqgc38-firefox-67.0.drv /nix/store/g6q0gx0v6xvdnizp8lrcw7c4gdkzana0-firefox-67.0 out');

where the hash 92a9... is a fingerprint over the flake store path and the contents of the lockfile. Because flakes are evaluated in pure mode, this uniquely identifies the evaluation result.

This exploits the hermetic nature of flake evaluation to speed up
repeated evaluations of a flake output attribute.

For example (doing 'nix build' on an already present package):

  $ time nix build nixpkgs:firefox

  real    0m1.497s
  user    0m1.160s
  sys     0m0.139s

  $ time nix build nixpkgs:firefox

  real    0m0.052s
  user    0m0.038s
  sys     0m0.007s

The cache is ~/.cache/nix/eval-cache-v1.sqlite, which has entries like

  INSERT INTO Attributes VALUES(
    X'92a907d4efe933af2a46959b082cdff176aa5bfeb47a98fabd234809a67ab195',
    'packages.firefox',
    1,
    '/nix/store/pbalzf8x19hckr8cwdv62rd6g0lqgc38-firefox-67.0.drv /nix/store/g6q0gx0v6xvdnizp8lrcw7c4gdkzana0-firefox-67.0 out');

where the hash 92a9... is a fingerprint over the flake store path and
the contents of the lockfile. Because flakes are evaluated in pure
mode, this uniquely identifies the evaluation result.
@edolstra edolstra changed the title Eval cache Flake evaluation cache Jun 7, 2019
@edolstra edolstra added the flakes label Jun 7, 2019
@edolstra edolstra requested review from CSVdB, shlevy and grahamc June 7, 2019 20:42
@edolstra edolstra merged commit c4d7401 into flakes Jun 11, 2019
@edolstra edolstra deleted the eval-cache branch June 11, 2019 10:13
SQLite(const SQLite & from) = delete;
SQLite& operator = (const SQLite & from) = delete;
SQLite& operator = (SQLite && from) { db = from.db; from.db = 0; return *this; }
~SQLite();
operator sqlite3 * () { return db; }

/* Disable synchronous mode, set truncate journal mode. */
void isCache();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just came across this in the source code. isCache really doesn't speak well for what it is doing. Maybe just calling it setTruncateJournalMode would have been better?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's an implementation detail. "isCache" is a more declarative statement - i.e. "this database is a cache so do whatever is possible to make it fast at the expensive of reliability".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first glance I would agree that setTruncateJournalMode seems to expose an implementation details and is thus maybe not ideal (On the other hand you added a comment saying "Disable synchronous mode, set truncate journal mode" because it would be very hard to derive that otherwise i guess)

From my point of view isCache is equally bad: My expectation is that any function adhering to a isSomething naming scheme falls into the category of predicate functions:

if (Something is satisfied) return true else return false

But isCache returns void and does some stuff that you cannot guess without reading the comment so i am not sure this is in fact very "declarative".

It's not entirely clear to me what the level of abstraction is here, and if isCache is part of some API or if it is only ever going to exist for SQLite.

  • If this will only ever exist in the context of SQLite then this is implementation specific already and then i'm not sure why this shouldn't actually say what it does.
  • if this is something that different storage classes will implement then I think a name like useAsCache would be more appropriate.

WDYT?

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

Successfully merging this pull request may close these issues.

None yet

3 participants