8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ //! A simple function caching system.
12
+ //!
13
+ //! This is a loose clone of the [fbuild build system](https://github.com/felix-lang/fbuild),
14
+ //! made a touch more generic (not wired to special cases on files) and much
15
+ //! less metaprogram-y due to rust's comparative weakness there, relative to
16
+ //! python.
17
+ //!
18
+ //! It's based around _imperative builds_ that happen to have some function
19
+ //! calls cached. That is, it's _just_ a mechanism for describing cached
20
+ //! functions. This makes it much simpler and smaller than a "build system"
21
+ //! that produces an IR and evaluates it. The evaluation order is normal
22
+ //! function calls. Some of them just return really quickly.
23
+ //!
24
+ //! A cached function consumes and produces a set of _works_. A work has a
25
+ //! name, a kind (that determines how the value is to be checked for
26
+ //! freshness) and a value. Works must also be (de)serializable. Some
27
+ //! examples of works:
28
+ //!
29
+ //! kind name value
30
+ //! ------------------------
31
+ //! cfg os linux
32
+ //! file foo.c <sha1>
33
+ //! url foo.com <etag>
34
+ //!
35
+ //! Works are conceptually single units, but we store them most of the time
36
+ //! in maps of the form (type,name) => value. These are WorkMaps.
37
+ //!
38
+ //! A cached function divides the works it's interested in into inputs and
39
+ //! outputs, and subdivides those into declared (input) works and
40
+ //! discovered (input and output) works.
41
+ //!
42
+ //! A _declared_ input or is one that is given to the workcache before
43
+ //! any work actually happens, in the "prep" phase. Even when a function's
44
+ //! work-doing part (the "exec" phase) never gets called, it has declared
45
+ //! inputs, which can be checked for freshness (and potentially
46
+ //! used to determine that the function can be skipped).
47
+ //!
48
+ //! The workcache checks _all_ works for freshness, but uses the set of
49
+ //! discovered outputs from the _previous_ exec (which it will re-discover
50
+ //! and re-record each time the exec phase runs).
51
+ //!
52
+ //! Therefore the discovered works cached in the db might be a
53
+ //! mis-approximation of the current discoverable works, but this is ok for
54
+ //! the following reason: we assume that if an artifact A changed from
55
+ //! depending on B,C,D to depending on B,C,D,E, then A itself changed (as
56
+ //! part of the change-in-dependencies), so we will be ok.
57
+ //!
58
+ //! Each function has a single discriminated output work called its _result_.
59
+ //! This is only different from other works in that it is returned, by value,
60
+ //! from a call to the cacheable function; the other output works are used in
61
+ //! passing to invalidate dependencies elsewhere in the cache, but do not
62
+ //! otherwise escape from a function invocation. Most functions only have one
63
+ //! output work anyways.
64
+ //!
65
+ //! A database (the central store of a workcache) stores a mappings:
66
+ //!
67
+ //! (fn_name,{declared_input}) => ({discovered_input},
68
+ //! {discovered_output},result)
69
+ //!
70
+ //! (Note: fbuild, which workcache is based on, has the concept of a declared
71
+ //! output as separate from a discovered output. This distinction exists only
72
+ //! as an artifact of how fbuild works: via annotations on function types
73
+ //! and metaprogramming, with explicit dependency declaration as a fallback.
74
+ //! Workcache is more explicit about dependencies, and as such treats all
75
+ //! outputs the same, as discovered-during-the-last-run.)
76
+
11
77
#![ crate_id = "workcache#0.11.0-pre" ]
12
78
#![ crate_type = "rlib" ]
13
79
#![ crate_type = "dylib" ]
@@ -33,74 +99,6 @@ use std::str;
33
99
use std:: io;
34
100
use std:: io:: { File , MemWriter } ;
35
101
36
- /**
37
- *
38
- * This is a loose clone of the [fbuild build system](https://github.com/felix-lang/fbuild),
39
- * made a touch more generic (not wired to special cases on files) and much
40
- * less metaprogram-y due to rust's comparative weakness there, relative to
41
- * python.
42
- *
43
- * It's based around _imperative builds_ that happen to have some function
44
- * calls cached. That is, it's _just_ a mechanism for describing cached
45
- * functions. This makes it much simpler and smaller than a "build system"
46
- * that produces an IR and evaluates it. The evaluation order is normal
47
- * function calls. Some of them just return really quickly.
48
- *
49
- * A cached function consumes and produces a set of _works_. A work has a
50
- * name, a kind (that determines how the value is to be checked for
51
- * freshness) and a value. Works must also be (de)serializable. Some
52
- * examples of works:
53
- *
54
- * kind name value
55
- * ------------------------
56
- * cfg os linux
57
- * file foo.c <sha1>
58
- * url foo.com <etag>
59
- *
60
- * Works are conceptually single units, but we store them most of the time
61
- * in maps of the form (type,name) => value. These are WorkMaps.
62
- *
63
- * A cached function divides the works it's interested in into inputs and
64
- * outputs, and subdivides those into declared (input) works and
65
- * discovered (input and output) works.
66
- *
67
- * A _declared_ input or is one that is given to the workcache before
68
- * any work actually happens, in the "prep" phase. Even when a function's
69
- * work-doing part (the "exec" phase) never gets called, it has declared
70
- * inputs, which can be checked for freshness (and potentially
71
- * used to determine that the function can be skipped).
72
- *
73
- * The workcache checks _all_ works for freshness, but uses the set of
74
- * discovered outputs from the _previous_ exec (which it will re-discover
75
- * and re-record each time the exec phase runs).
76
- *
77
- * Therefore the discovered works cached in the db might be a
78
- * mis-approximation of the current discoverable works, but this is ok for
79
- * the following reason: we assume that if an artifact A changed from
80
- * depending on B,C,D to depending on B,C,D,E, then A itself changed (as
81
- * part of the change-in-dependencies), so we will be ok.
82
- *
83
- * Each function has a single discriminated output work called its _result_.
84
- * This is only different from other works in that it is returned, by value,
85
- * from a call to the cacheable function; the other output works are used in
86
- * passing to invalidate dependencies elsewhere in the cache, but do not
87
- * otherwise escape from a function invocation. Most functions only have one
88
- * output work anyways.
89
- *
90
- * A database (the central store of a workcache) stores a mappings:
91
- *
92
- * (fn_name,{declared_input}) => ({discovered_input},
93
- * {discovered_output},result)
94
- *
95
- * (Note: fbuild, which workcache is based on, has the concept of a declared
96
- * output as separate from a discovered output. This distinction exists only
97
- * as an artifact of how fbuild works: via annotations on function types
98
- * and metaprogramming, with explicit dependency declaration as a fallback.
99
- * Workcache is more explicit about dependencies, and as such treats all
100
- * outputs the same, as discovered-during-the-last-run.)
101
- *
102
- */
103
-
104
102
#[ deriving( Clone , Eq , Encodable , Decodable , Ord , TotalOrd , TotalEq ) ]
105
103
struct WorkKey {
106
104
kind : StrBuf ,
0 commit comments