diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-01-20 12:38:06 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-01-20 12:38:06 +0200 |
commit | 699e3bc87d1cbb3c2b19ddaf5db37909cb49f47b (patch) | |
tree | a79a11758bfd58b38a14459e1b268843d14ca67e /build2/prerequisite | |
parent | ea8f6e4aeb120117c72b87da398eeebb35fe192a (diff) |
Remove prerequisite caching in scope
We don't share them often and those that are shared (e.g., cxx{} in
obja/objs{}) are lightweight (SOO).
Diffstat (limited to 'build2/prerequisite')
-rw-r--r-- | build2/prerequisite | 132 |
1 files changed, 27 insertions, 105 deletions
diff --git a/build2/prerequisite b/build2/prerequisite index 60970d6..f951e0a 100644 --- a/build2/prerequisite +++ b/build2/prerequisite @@ -5,7 +5,6 @@ #ifndef BUILD2_PREREQUISITE #define BUILD2_PREREQUISITE -#include <functional> // hash #include <unordered_set> #include <build2/types> @@ -22,6 +21,11 @@ namespace build2 // Light-weight (by being shallow-pointing) prerequisite key, similar // to (and based on) target key. // + // Note that unlike prerequisite, the key is not (necessarily) owned by a + // target. So for the key we instead have the base scope of the target that + // (would) own it. Note that we assume keys to be ephemeral enough for the + // base scope to remain unchanged. + // class prerequisite_key { public: @@ -38,52 +42,14 @@ namespace build2 bool is_a (const target_type& tt) const {return tk.is_a (tt);} }; - inline bool - operator== (const prerequisite_key& x, const prerequisite_key& y) - { - assert (x.scope == y.scope); - return x.proj == y.proj && x.tk == y.tk; - } - - inline bool - operator!= (const prerequisite_key& x, const prerequisite_key& y) - { - return !(x == y); - } - ostream& operator<< (ostream&, const prerequisite_key&); -} - - -namespace std -{ - // Note that we ignore the extension when calculating the hash because of - // its special "unspecified" logic (see target_key::operator==). - // - template <> - struct hash<build2::prerequisite_key> - { - using argument_type = build2::prerequisite_key; - using result_type = size_t; - - size_t - operator() (const build2::prerequisite_key& k) const noexcept - { - return build2::combine_hash (hash<build2::optional<string>> () (k.proj), - hash<build2::target_key> () (k.tk)); - } - }; -} -namespace build2 -{ class prerequisite { public: typedef build2::target target_type; typedef build2::target_type target_type_type; - typedef build2::scope scope_type; // Note that unlike targets, for prerequisites an empty out directory // means undetermined rather than being definitely in the out tree. @@ -94,7 +60,9 @@ namespace build2 const dir_path out; // Empty, normalized absolute, or relative. const string name; const optional<string> ext; // Absent if unspecified. - scope_type& scope; + + target_type& owner; // Target to which this prerequisite belongs. + target_type* target; // NULL if not yet resolved. Note that this // should always be the "primary target", not // a member of a target group. @@ -106,28 +74,40 @@ namespace build2 dir_path o, string n, optional<string> e, - scope_type& s) + target_type& w) : proj (move (p)), type (t), dir (move (d)), out (move (o)), name (move (n)), ext (move (e)), - scope (s), + owner (w), target (nullptr) {} + // Make a copy for a new owner target. Note that both owner targets should + // be in the same scope. + // + prerequisite (const prerequisite&, target_type& owner); + + // Make a prerequisite from a target. + // + prerequisite (target_type&, target_type& owner); + + prerequisite (const prerequisite&) = delete; + prerequisite (prerequisite&&) = default; + + prerequisite& operator= (const prerequisite&) = delete; + prerequisite& operator= (prerequisite&&) = default; + // Note that the returned key "tracks" the prerequisite; that is, any // updates to the prerequisite's members will be reflected in the key. // prerequisite_key - key () const - { - return prerequisite_key {proj, {&type, &dir, &out, &name, ext}, &scope}; - } + key () const; - public: // Prerequisite (target) type. // + public: template <typename T> bool is_a () const {return type.is_a<T> ();} @@ -136,69 +116,11 @@ namespace build2 is_a (const target_type_type& tt) const {return type.is_a (tt);} }; - inline bool - operator== (const prerequisite& x, const prerequisite& y) - { - return x.key () == y.key (); - } - - inline bool - operator!= (const prerequisite& x, const prerequisite& y) - { - return !(x == y); - } - inline ostream& operator<< (ostream& os, const prerequisite& p) { return os << p.key (); } - -} - -namespace std -{ - template <> - struct hash<build2::prerequisite> - { - using argument_type = build2::prerequisite; - using result_type = size_t; - - size_t - operator() (const build2::prerequisite& p) const noexcept - { - return hash<build2::prerequisite_key> () (p.key ()); - } - }; -} - -namespace build2 -{ - // Set of prerequisites in a scope. - // - // Similar to targets, specified and unspecified extensions are considered - // equal and we may update the extension in the existing entry. To make - // this work we use a hash set. - // - struct prerequisite_set: std::unordered_set<prerequisite> - { - pair<prerequisite&, bool> - insert (optional<string> proj, - const target_type&, - dir_path dir, - dir_path out, - string name, - optional<string> ext, - scope&, - tracer&); - - pair<prerequisite&, bool> - insert (optional<string> proj, const target_key& tk, scope& s, tracer& t) - { - return insert ( - move (proj), *tk.type, *tk.dir, *tk.out, *tk.name, tk.ext, s, t); - } - }; } #endif // BUILD2_PREREQUISITE |