[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

07/07: store: Add a functional object cache and use it in 'lower-object'

From: Ludovic Courtès
Subject: 07/07: store: Add a functional object cache and use it in 'lower-object'.
Date: Fri, 20 Nov 2015 22:39:03 +0000

civodul pushed a commit to branch wip-build-systems-gexp
in repository guix.

commit 4c2ade20c65e94c41dc8c65db73dd128343a0ad5
Author: Ludovic Courtès <address@hidden>
Date:   Fri Nov 20 18:44:29 2015 +0100

    store: Add a functional object cache and use it in 'lower-object'.
    * guix/store.scm (<nix-server>)[object-cache]: New field.
    * guix/store.scm (open-connection): Initialize it.
    (cache-object-mapping, lookup-cached-object, %mcached): New procedures.
    (mcached): New macro.
    * guix/gexp.scm (lower-object): Use it.
    * guix/derivations.scm (grafting?): New procedure.
 guix/derivations.scm |    6 +++++
 guix/gexp.scm        |    8 +++++-
 guix/store.scm       |   57 +++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/guix/derivations.scm b/guix/derivations.scm
index 342a6c8..57ac71a 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -100,6 +100,7 @@
+            grafting?
 it otherwise.  It returns the previous setting."
   (lambda (store)
     (values (%graft? enable?) store)))
+(define (grafting?)
+  "This monadic procedure turns #t when grafting is enabled, #f otherwise."
+  (lambda (store)
+    (values (%graft?) store)))
diff --git a/guix/gexp.scm b/guix/gexp.scm
index c5f3d4c..72f2b40 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -156,8 +156,12 @@ procedure to lower it; otherwise return #f."
 corresponding to OBJ for SYSTEM, cross-compiling for TARGET if TARGET is true.
 OBJ must be an object that has an associated gexp compiler, such as a
-  (let ((lower (lookup-compiler obj)))
-    (lower obj system target)))
+  ;; Cache in STORE the result of lowering OBJ.
+  (mlet %store-monad ((graft? (grafting?)))
+    (mcached (let ((lower (lookup-compiler obj)))
+               (lower obj system target))
+             obj
+             system target graft?)))
 (define-syntax-rule (define-gexp-compiler (name (param predicate)
                                                 system target)
diff --git a/guix/store.scm b/guix/store.scm
index c4e3573..7c18829 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -21,6 +21,7 @@
   #:use-module (guix config)
   #:use-module (guix serialization)
   #:use-module (guix monads)
+  #:use-module (guix records)
   #:autoload   (guix base32) (bytevector->base32-string)
   #:use-module (rnrs bytevectors)
   #:use-module (rnrs io ports)
@@ -43,6 +44,7 @@
+            mcached
             &nix-error nix-error?
             &nix-connection-error nix-connection-error?
@@ -292,9 +294,7 @@
-(define-record-type <nix-server>
-  (%make-nix-server socket major minor
-                    ats-cache atts-cache)
+(define-record-type* <nix-server> nix-server %make-nix-server
   (socket nix-server-socket)
   (major  nix-server-major-version)
@@ -304,7 +304,9 @@
   ;; during the session are temporary GC roots kept for the duration of
   ;; the session.
   (ats-cache  nix-server-add-to-store-cache)
-  (atts-cache nix-server-add-text-to-store-cache))
+  (atts-cache nix-server-add-text-to-store-cache)
+  (object-cache nix-server-object-cache
+                (default vlist-null)))            ;vhash
 (set-record-type-printer! <nix-server>
                           (lambda (obj port)
@@ -361,7 +363,8 @@ operate, should the disk become full.  Return a server 
                                                (protocol-major v)
                                                (protocol-minor v)
                                                (make-hash-table 100)
-                                               (make-hash-table 100))))
+                                               (make-hash-table 100)
+                                               vlist-null)))
                       (let loop ((done? (process-stderr s)))
                         (or done? (process-stderr s)))
@@ -951,6 +954,50 @@ be used internally by the daemon's build hook."
 (define-alias store-return state-return)
 (define-alias store-bind state-bind)
+(define* (cache-object-mapping object keys result)
+  "Augment the store's object cache with a mapping from OBJECT/KEYS to RESULT.
+KEYS is a list of additional keys to match against, for instance a (SYSTEM
+TARGET) tuple.
+OBJECT is typically a high-level object such as a <package> or an <origin>,
+and RESULT is typically its derivation."
+  (lambda (store)
+    (values result
+            (nix-server
+             (inherit store)
+             (object-cache (vhash-consq object (cons result keys)
+                                        (nix-server-object-cache store)))))))
+(define* (lookup-cached-object object #:optional (keys '()))
+  "Return the cached object in the store connection corresponding to OBJECT
+and KEYS.  KEYS is a list of additional keys to match against, and which are
+compared with 'equal?'.  Return #f on failure and the cached result
+  (lambda (store)
+    (values (any (match-lambda
+                   ((result . keys*)
+                    (and (equal? keys keys*) result)))
+                 (vhash-foldq* cons '() object
+                               (nix-server-object-cache store)))
+            store)))
+(define* (%mcached mthunk object #:optional (keys '()))
+  "Bind the monadic value returned by MTHUNK, which supposedly corresponds to
+OBJECT/KEYS, or return its cached value."
+  (mlet %store-monad ((cached (lookup-cached-object object keys)))
+    (if cached
+        (return cached)
+        (>>= (mthunk)
+             (lambda (result)
+               (cache-object-mapping object keys result))))))
+(define-syntax-rule (mcached mvalue object keys ...)
+  "Run MVALUE, which corresponds to OBJECT/KEYS, and cache it; or return the
+value associated with OBJECT/KEYS in the store's object cache if there is
+  (%mcached (lambda () mvalue)
+            object (list keys ...)))
 (define (preserve-documentation original proc)
   "Return PROC with documentation taken from ORIGINAL."
   (set-object-property! proc 'documentation

reply via email to

[Prev in Thread] Current Thread [Next in Thread]