ADD Statistics outputs
3 files changed, 150 insertions(+), 113 deletions(-)

M README.md
M README.org
M src/pds/pds.ml
M README.md +120 -112
@@ 2,65 2,66 @@ 
 
 # Table of Contents
 
-1.  [About](#orgb980c09)
-    1.  [Why Does This Exist?](#org56fd24d)
-2.  [Parallelism](#org81a3827)
-3.  [Content Hash Based Builds](#org7f92baf)
-4.  [Terminology](#org42d24bb)
-5.  [Projects](#org9476662)
-    1.  [Ocaml](#org1fb3a5d)
-    2.  [Third-party](#org3c89308)
-6.  [Dependencies](#org5e5df41)
-7.  [Configuration](#orgd67db70)
-    1.  [Configuration Variables For Projects](#org215ac13)
-    2.  [Configuration Variables For Tests](#orgb54c88a)
-    3.  [Outputting the configuration](#orgd97e2c1)
-8.  [Produced Files](#org4c19386)
-9.  [Documentation](#org1f0ce9f)
-10. [Selectors](#org9f09373)
-11. [Changelog](#org673756c)
-    1.  [1.0.0](#org1997bcd)
-    2.  [1.1.0](#orgd74e9a5)
-    3.  [2.0.0](#org7a866a9)
-    4.  [3.0.0](#org672d98f)
-    5.  [3.0.1](#orgc99efed)
-    6.  [3.0.2](#orgd4ebec4)
-    7.  [3.0.3](#org50cef80)
-    8.  [3.0.4](#orgaa2ae45)
-    9.  [3.1.0](#org7bf1c5c)
-    10. [3.1.1](#org33043f8)
-    11. [4.11](#org8c6e88f)
-    12. [4.12](#org5b03cc2)
-    13. [4.13](#org35dc9c1)
-    14. [5.14](#orgec52927)
-    15. [5.15](#orge67d5bd)
-    16. [5.16](#org2d4076c)
-    17. [5.17 (bug release)](#org58e6a49)
-    18. [5.18](#org3e619cc)
-    19. [5.19](#org93c9f01)
-    20. [6.20](#org5c202e5)
-    21. [5.21](#orgb20adf2)
-    22. [5.22](#orge87db73)
-    23. [5.23](#org18b9b45)
-    24. [5.24](#org35c90dc)
-    25. [5.25](#orgcd22eea)
-    26. [5.26 (bug release)](#org5f42e3e)
-    27. [5.27](#org0f1562c)
-    28. [5.28](#orge396426)
-    29. [5.29](#org03bb570)
-    30. [6.43](#org3a99c0a)
-    31. [6.44](#orgf02e9d4)
-    32. [6.45](#org6ab11f6)
-    33. [6.46](#org7b3352d)
-    34. [6.47](#orgb8a8e74)
-    35. [6.48](#org745abb1)
-    36. [6.49](#orgbefe34e)
-    37. [6.50](#orgad57571)
-    38. [6.51](#orgb80bf2c)
-    39. [6.52](#orgb02e4a8)
+1.  [About](#orga360c70)
+    1.  [Why Does This Exist?](#org8949d9d)
+2.  [Parallelism](#org1e4b62d)
+3.  [Content Hash Based Builds](#orgbcfffdf)
+4.  [Terminology](#orgb23734c)
+5.  [Projects](#org5b36ffd)
+    1.  [Ocaml](#org3776fc4)
+    2.  [Third-party](#orgd58d1a0)
+6.  [Dependencies](#org392904b)
+7.  [Configuration](#org42b985d)
+    1.  [Configuration Variables For Projects](#org5d87c22)
+    2.  [Configuration Variables For Tests](#org4681a6b)
+    3.  [Outputting the configuration](#orge94f603)
+8.  [Produced Files](#orga026686)
+9.  [Documentation](#orge030a03)
+10. [Selectors](#orgd23537d)
+11. [Changelog](#org30440c2)
+    1.  [1.0.0](#org5ca1d41)
+    2.  [1.1.0](#org301605a)
+    3.  [2.0.0](#org33f2726)
+    4.  [3.0.0](#org57f1f53)
+    5.  [3.0.1](#org1268417)
+    6.  [3.0.2](#org9d385e6)
+    7.  [3.0.3](#org4138945)
+    8.  [3.0.4](#orgaf4414d)
+    9.  [3.1.0](#orgeb31c57)
+    10. [3.1.1](#org2947ecb)
+    11. [4.11](#org50e1cda)
+    12. [4.12](#orgb64db83)
+    13. [4.13](#org7e847e3)
+    14. [5.14](#orgee36618)
+    15. [5.15](#org4c3725d)
+    16. [5.16](#org2d5ff93)
+    17. [5.17 (bug release)](#orgefacc93)
+    18. [5.18](#orge1302eb)
+    19. [5.19](#org706bf6c)
+    20. [6.20](#org3ab1579)
+    21. [5.21](#org0dbcb50)
+    22. [5.22](#org693359a)
+    23. [5.23](#org9b92c02)
+    24. [5.24](#org9e146be)
+    25. [5.25](#org54720da)
+    26. [5.26 (bug release)](#orgbb52346)
+    27. [5.27](#org29b391d)
+    28. [5.28](#org5e043d1)
+    29. [5.29](#org6252aca)
+    30. [6.43](#orgb4bdb52)
+    31. [6.44](#org6c4245d)
+    32. [6.45](#org5b7c68e)
+    33. [6.46](#orgf21b296)
+    34. [6.47](#org459540f)
+    35. [6.48](#orgc195d05)
+    36. [6.49](#org202d811)
+    37. [6.50](#orgadcfb1d)
+    38. [6.51](#org9d2d027)
+    39. [6.52](#orge90920a)
+    40. [6.53](#org79afb23)
 
 
-<a id="orgb980c09"></a>
+<a id="orga360c70"></a>
 
 # About
 

          
@@ 127,7 128,7 @@ the `build` directory, for example `buil
 `build/test-release`.
 
 
-<a id="org56fd24d"></a>
+<a id="org8949d9d"></a>
 
 ## Why Does This Exist?
 

          
@@ 140,7 141,7 @@ the existing tooling then you should be 
 meant to be non-intrusive.
 
 
-<a id="org81a3827"></a>
+<a id="org1e4b62d"></a>
 
 # Parallelism
 

          
@@ 160,7 161,7 @@ the source of the `units Foo and Bar mak
 error.
 
 
-<a id="org7f92baf"></a>
+<a id="orgbcfffdf"></a>
 
 # Content Hash Based Builds
 

          
@@ 180,7 181,7 @@ of the build configuration, this ensure 
 that causes a rebuild.
 
 
-<a id="org42d24bb"></a>
+<a id="orgb23734c"></a>
 
 # Terminology
 

          
@@ 192,7 193,7 @@ that causes a rebuild.
     `library`, this applies only to ocaml projects..
 
 
-<a id="org9476662"></a>
+<a id="org5b36ffd"></a>
 
 # Projects
 

          
@@ 203,7 204,7 @@ interface, which is `release`, `debug`, 
 and `clean`.
 
 
-<a id="org1fb3a5d"></a>
+<a id="org3776fc4"></a>
 
 ## Ocaml
 

          
@@ 254,7 255,7 @@ generated.
 </table>
 
 
-<a id="org3c89308"></a>
+<a id="orgd58d1a0"></a>
 
 ## Third-party
 

          
@@ 262,7 263,7 @@ Third party projects do not have a `Make
 to have one which corresponds to the pds interface.
 
 
-<a id="org5e5df41"></a>
+<a id="org392904b"></a>
 
 # Dependencies
 

          
@@ 273,7 274,7 @@ compiled before its dependent project an
 as a dependency in the dependents `Makefile`.
 
 
-<a id="orgd67db70"></a>
+<a id="org42b985d"></a>
 
 # Configuration
 

          
@@ 327,7 328,7 @@ An example of building the example direc
     install = false
 
 
-<a id="org215ac13"></a>
+<a id="org5d87c22"></a>
 
 ## Configuration Variables For Projects
 

          
@@ 477,7 478,7 @@ 5.  `src.<project>.<option>`
 The same precedence applies to test builds.
 
 
-<a id="orgb54c88a"></a>
+<a id="org4681a6b"></a>
 
 ## Configuration Variables For Tests
 

          
@@ 492,7 493,7 @@ 2.  `global.test-<build_type>.<option>`
 3.  `tests.<project>.<option>`
 
 
-<a id="orgd97e2c1"></a>
+<a id="orge94f603"></a>
 
 ## Outputting the configuration
 

          
@@ 549,7 550,7 @@ output looks like the following:
 </table>
 
 
-<a id="org4c19386"></a>
+<a id="orga026686"></a>
 
 # Produced Files
 

          
@@ 562,7 563,7 @@ ignored in the form of a `.gitignore`.
     Ocamlrules.mk.in
 
 
-<a id="org1f0ce9f"></a>
+<a id="orge030a03"></a>
 
 # Documentation
 

          
@@ 576,7 577,7 @@ also be set for `ocamldoc` by modifying 
 `extra_makefile_lines`.
 
 
-<a id="org9f09373"></a>
+<a id="orgd23537d"></a>
 
 # Selectors
 

          
@@ 620,12 621,12 @@ The order of precedence is that the sele
 checked, then the selector for a release.
 
 
-<a id="org673756c"></a>
+<a id="org30440c2"></a>
 
 # Changelog
 
 
-<a id="org1997bcd"></a>
+<a id="org5ca1d41"></a>
 
 ## 1.0.0
 

          
@@ 634,7 635,7 @@ checked, then the selector for a release
 -   Support running tests.
 
 
-<a id="orgd74e9a5"></a>
+<a id="org301605a"></a>
 
 ## 1.1.0
 

          
@@ 643,7 644,7 @@ checked, then the selector for a release
     is useful if a tool needs to be built that will be used to compile a project.
 
 
-<a id="org7a866a9"></a>
+<a id="org33f2726"></a>
 
 ## 2.0.0
 

          
@@ 652,7 653,7 @@ checked, then the selector for a release
 -   Fill out the documentation more.
 
 
-<a id="org672d98f"></a>
+<a id="org57f1f53"></a>
 
 ## 3.0.0
 

          
@@ 660,7 661,7 @@ checked, then the selector for a release
     understands both installing and uninstalling projects.
 
 
-<a id="orgc99efed"></a>
+<a id="org1268417"></a>
 
 ## 3.0.1
 

          
@@ 668,14 669,14 @@ checked, then the selector for a release
     after using hll to make the package.
 
 
-<a id="orgd4ebec4"></a>
+<a id="org9d385e6"></a>
 
 ## 3.0.2
 
 -   Expand the hll config to pass opam-linter.
 
 
-<a id="org50cef80"></a>
+<a id="org4138945"></a>
 
 ## 3.0.3
 

          
@@ 683,7 684,7 @@ checked, then the selector for a release
 -   Specify which version of ocaml pds works with.
 
 
-<a id="orgaa2ae45"></a>
+<a id="orgaf4414d"></a>
 
 ## 3.0.4
 

          
@@ 691,7 692,7 @@ checked, then the selector for a release
 -   Remove examples.
 
 
-<a id="org7bf1c5c"></a>
+<a id="orgeb31c57"></a>
 
 ## 3.1.0
 

          
@@ 699,14 700,14 @@ checked, then the selector for a release
 -   Install `.cmi` files.
 
 
-<a id="org33043f8"></a>
+<a id="org2947ecb"></a>
 
 ## 3.1.1
 
 -   Fix a bug in generating docs when the project has no dependencies.
 
 
-<a id="org8c6e88f"></a>
+<a id="org50e1cda"></a>
 
 ## 4.11
 

          
@@ 717,21 718,21 @@ checked, then the selector for a release
     name of the output.
 
 
-<a id="org5b03cc2"></a>
+<a id="orgb64db83"></a>
 
 ## 4.12
 
 -   Include tests directories in formatted output.
 
 
-<a id="org35dc9c1"></a>
+<a id="org7e847e3"></a>
 
 ## 4.13
 
 -   Make a better error message for the install key, which is required.
 
 
-<a id="orgec52927"></a>
+<a id="orgee36618"></a>
 
 ## 5.14
 

          
@@ 741,7 742,7 @@ checked, then the selector for a release
 -   Remove PACK support.  Building PACKs is no longer supported.
 
 
-<a id="orge67d5bd"></a>
+<a id="org4c3725d"></a>
 
 ## 5.15
 

          
@@ 749,14 750,14 @@ checked, then the selector for a release
 -   Add a changelog and back fill it.
 
 
-<a id="org2d4076c"></a>
+<a id="org2d5ff93"></a>
 
 ## 5.16
 
 -   Fix bug in cleanup logic which concatenated multiple deps
 
 
-<a id="org58e6a49"></a>
+<a id="orgefacc93"></a>
 
 ## 5.17 (bug release)
 

          
@@ 767,7 768,7 @@ checked, then the selector for a release
     first then the .cmo and .cmx are generated.
 
 
-<a id="org3e619cc"></a>
+<a id="orge1302eb"></a>
 
 ## 5.18
 

          
@@ 780,7 781,7 @@ checked, then the selector for a release
     it.  This solves it by serializing the build for those cases.
 
 
-<a id="org93c9f01"></a>
+<a id="org706bf6c"></a>
 
 ## 5.19
 

          
@@ 788,14 789,14 @@ checked, then the selector for a release
     installs `.cmi` files for all `.ml` files.
 
 
-<a id="org5c202e5"></a>
+<a id="org3ab1579"></a>
 
 ## 6.20
 
 -   Removed the `-custom` option from default byte code builds.
 
 
-<a id="orgb20adf2"></a>
+<a id="org0dbcb50"></a>
 
 ## 5.21
 

          
@@ 803,7 804,7 @@ checked, then the selector for a release
     them to be overridden.
 
 
-<a id="orge87db73"></a>
+<a id="org693359a"></a>
 
 ## 5.22
 

          
@@ 811,28 812,28 @@ checked, then the selector for a release
 -   Tests compile with `OCAML*_LINK_OPTS` just like regular builds.
 
 
-<a id="org18b9b45"></a>
+<a id="org9b92c02"></a>
 
 ## 5.23
 
 -   Fix typo in PARALLEL
 
 
-<a id="org35c90dc"></a>
+<a id="org9e146be"></a>
 
 ## 5.24
 
 -   Build cmti files and install them for every library.
 
 
-<a id="orgcd22eea"></a>
+<a id="org54720da"></a>
 
 ## 5.25
 
 -   Support adding linkopts to the META file.
 
 
-<a id="org5f42e3e"></a>
+<a id="orgbb52346"></a>
 
 ## 5.26 (bug release)
 

          
@@ 840,14 841,14 @@ checked, then the selector for a release
 -   Add some tests.
 
 
-<a id="org0f1562c"></a>
+<a id="org29b391d"></a>
 
 ## 5.27
 
 -   Fix bug in section name for the selector.
 
 
-<a id="orge396426"></a>
+<a id="org5e043d1"></a>
 
 ## 5.28
 

          
@@ 855,7 856,7 @@ checked, then the selector for a release
     were not properly looked up.
 
 
-<a id="org03bb570"></a>
+<a id="org6252aca"></a>
 
 ## 5.29
 

          
@@ 864,56 865,56 @@ checked, then the selector for a release
     worked).
 
 
-<a id="org3a99c0a"></a>
+<a id="orgb4bdb52"></a>
 
 ## 6.43
 
 -   Move to content based hashing.
 
 
-<a id="orgf02e9d4"></a>
+<a id="org6c4245d"></a>
 
 ## 6.44
 
 -   Fix install directive
 
 
-<a id="org6ab11f6"></a>
+<a id="org5b7c68e"></a>
 
 ## 6.45
 
 -   Better sqlite error reporting
 
 
-<a id="org7b3352d"></a>
+<a id="orgf21b296"></a>
 
 ## 6.46
 
 -   strftime usage that works on Alpine
 
 
-<a id="orgb8a8e74"></a>
+<a id="org459540f"></a>
 
 ## 6.47
 
 -   Another instance of strftime
 
 
-<a id="org745abb1"></a>
+<a id="orgc195d05"></a>
 
 ## 6.48
 
 -   Fix bugs in testing outputs.
 
 
-<a id="orgbefe34e"></a>
+<a id="org202d811"></a>
 
 ## 6.49
 
 -   Improve performance 10x by batching database operations.
 
 
-<a id="orgad57571"></a>
+<a id="orgadcfb1d"></a>
 
 ## 6.50
 

          
@@ 921,16 922,23 @@ checked, then the selector for a release
     that its hash had been changed, when in reality it didn't exist.
 
 
-<a id="orgb80bf2c"></a>
+<a id="org9d2d027"></a>
 
 ## 6.51
 
 -   Remove target files from build dir when a file is deleted
 
 
-<a id="orgb02e4a8"></a>
+<a id="orge90920a"></a>
 
 ## 6.52
 
 -   Fix timezone issues in managing file modification times
 
+
+<a id="org79afb23"></a>
+
+## 6.53
+
+-   Add statistics output
+

          
M README.org +2 -0
@@ 439,3 439,5 @@ checked, then the selector for a release
 - Remove target files from build dir when a file is deleted
 ** 6.52
 - Fix timezone issues in managing file modification times
+** 6.53
+- Add statistics output

          
M src/pds/pds.ml +28 -1
@@ 585,7 585,7 @@ module Hash_db = struct
     assert_rc rc;
     if rows <> [] then remove_deleted_files srcs tests rows;
     (* Move files with different hashes into hashes table. *)
-    Logs.debug (fun m -> m "set modified_at to in last_run to hashes for matching file hashes");
+    Logs.debug (fun m -> m "set modified_at in last_run to hashes for matching file hashes");
     assert_rc
     @@ Sqlite3.exec
          db

          
@@ 596,6 596,33 @@ module Hash_db = struct
     assert_rc @@ Sqlite3.exec db "drop table hashes";
     Logs.debug (fun m -> m "rename last_run to hashes");
     assert_rc @@ Sqlite3.exec db "alter table last_run rename to hashes";
+    Logs.debug (fun m -> m "get statistics");
+    let stmt =
+      Sqlite3.prepare db "select count(path), min(modified_at), max(modified_at) from hashes"
+    in
+    let rc, rows =
+      Sqlite3.fold
+        stmt
+        ~f:(fun acc row ->
+          match row with
+          | Sqlite3.Data.[| INT count; TEXT min_modified_at; TEXT max_modified_at |] ->
+              (count, min_modified_at, max_modified_at) :: acc
+          | _ -> acc)
+        ~init:[]
+    in
+    assert_rc rc;
+    assert_rc @@ Sqlite3.finalize stmt;
+    let count, min_modified_at, max_modified_at =
+      match rows with
+      | v :: _ -> v
+      | [] -> assert false
+    in
+    Logs.info (fun m ->
+        m
+          "file count : %d : min modified_at : %s max modified_at : %s"
+          (Int64.to_int count)
+          min_modified_at
+          max_modified_at);
     ignore (Sqlite3.db_close db);
     ()
 end