summaryrefslogtreecommitdiff
path: root/tests/store-deduplication.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2024-04-19 22:00:44 +0200
committerLudovic Courtès <ludo@gnu.org>2024-05-25 16:44:42 +0200
commit5a7cb59648d102168bd4ecd16f36b69e0f594be1 (patch)
treee29fb395373468bc9e041f8e39de7a30112cdfe9 /tests/store-deduplication.scm
parent73b3f941d7d911a1b2bb2bf77d37cb3a12ed4291 (diff)
deduplication: Detect holes and create sparse files.
This reduces disk usage of sparse files that are substituted such as Guile object files (ELF files). As of Guile 3.0.9, .go files are sparse due to ELF sections being aligned on 64 KiB boundaries. This reduces disk usage reported by “du -sh” by 9% for the ‘guix’ package, by 23% for ‘guile’, and by 35% for ‘guile-git’. * guix/store/deduplication.scm (hole-size, find-holes): New procedures. (tee)[seekable?]: New variable. [read!]: Add case when SEEKABLE? is true. * tests/store-deduplication.scm (cartesian-product): New procedure. ("copy-file/deduplicate, sparse files (holes: ~a/~a/~a)"): New test set. Change-Id: Iad2ab7830dcb1220e2026f4a127a6c718afa8964
Diffstat (limited to 'tests/store-deduplication.scm')
-rw-r--r--tests/store-deduplication.scm58
1 files changed, 57 insertions, 1 deletions
diff --git a/tests/store-deduplication.scm b/tests/store-deduplication.scm
index f1845035d89..f116ff9834e 100644
--- a/tests/store-deduplication.scm
+++ b/tests/store-deduplication.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2018, 2020-2022 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2018, 2020-2022, 2024 Ludovic Courtès <ludo@gnu.org>
3;;; 3;;;
4;;; This file is part of GNU Guix. 4;;; This file is part of GNU Guix.
5;;; 5;;;
@@ -24,10 +24,27 @@
24 #:use-module (guix build utils) 24 #:use-module (guix build utils)
25 #:use-module (rnrs bytevectors) 25 #:use-module (rnrs bytevectors)
26 #:use-module (ice-9 binary-ports) 26 #:use-module (ice-9 binary-ports)
27 #:use-module (ice-9 match)
27 #:use-module (srfi srfi-1) 28 #:use-module (srfi srfi-1)
28 #:use-module (srfi srfi-26) 29 #:use-module (srfi srfi-26)
29 #:use-module (srfi srfi-64)) 30 #:use-module (srfi srfi-64))
30 31
32(define (cartesian-product . lst)
33 "Return the Cartesian product of all the given lists."
34 (match lst
35 ((head)
36 (map list head))
37 ((head . rest)
38 (let ((others (apply cartesian-product rest)))
39 (append-map (lambda (init)
40 (map (lambda (lst)
41 (cons init lst))
42 others))
43 head)))
44 (()
45 '())))
46
47
31(test-begin "store-deduplication") 48(test-begin "store-deduplication")
32 49
33(test-equal "deduplicate, below %deduplication-minimum-size" 50(test-equal "deduplicate, below %deduplication-minimum-size"
@@ -166,4 +183,43 @@
166 (cut string-append store <>)) 183 (cut string-append store <>))
167 '("/a" "/b" "/c")))))))) 184 '("/a" "/b" "/c"))))))))
168 185
186(for-each (match-lambda
187 ((initial-gap middle-gap final-gap)
188 (test-assert
189 (format #f "copy-file/deduplicate, sparse files (holes: ~a/~a/~a)"
190 initial-gap middle-gap final-gap)
191 (call-with-temporary-directory
192 (lambda (store)
193 (let ((source (string-append store "/source")))
194 (call-with-output-file source
195 (lambda (port)
196 (seek port initial-gap SEEK_CUR)
197 (display "hi!" port)
198 (seek port middle-gap SEEK_CUR)
199 (display "bye." port)
200 (when (> final-gap 0)
201 (seek port (- final-gap 1) SEEK_CUR)
202 (put-u8 port 0))))
203
204 (for-each (lambda (target)
205 (copy-file/deduplicate source
206 (string-append store target)
207 #:store store))
208 '("/a" "/b" "/c"))
209 (system* "du" "-h" source)
210 (system* "du" "-h" "--apparent-size" source)
211 (system* "du" "-h" (string-append store "/a"))
212 (system* "du" "-h" "--apparent-size" (string-append store "/a"))
213 (and (directory-exists? (string-append store "/.links"))
214 (file=? source (string-append store "/a"))
215 (apply = (map (compose stat:ino stat
216 (cut string-append store <>))
217 '("/a" "/b" "/c")))
218 (let ((st (pk 'S (stat (string-append store "/a")))))
219 (<= (* 512 (stat:blocks st))
220 (stat:size st))))))))))
221 (cartesian-product '(0 3333 8192)
222 '(8192 9999 16384 22222)
223 '(0 8192)))
224
169(test-end "store-deduplication") 225(test-end "store-deduplication")