• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef TOOLS_GN_RESOLVED_TARGET_DEPS_H_
6 #define TOOLS_GN_RESOLVED_TARGET_DEPS_H_
7 
8 #include "base/containers/span.h"
9 #include "gn/label_ptr.h"
10 
11 #include <memory>
12 
13 // A class used to record the dependencies of a given Target in
14 // a way that is much more efficient to iterate over than having three
15 // separate LabelTargetVector instances. Technically equivalent to
16 // DepsIterator, but profiling shows that this class is much faster
17 // to use during graph-traversal heavy operations.
18 //
19 // Usage is:
20 //   1) Create instance, passing const references to the LabelTargetVector
21 //      instances for the private, public and data deps for the target.
22 //
23 //   2) Use private_deps(), public_deps(), data_deps(), linked_deps()
24 //      and all_deps() to retrieve spans that cover various subsets of
25 //      interests. These can be used directly in for-range loops as in:
26 //
27 //       for (const Target* target : resolved.linked_deps()) {
28 //         ..
29 //       }
30 //
31 class ResolvedTargetDeps {
32  public:
33   ResolvedTargetDeps() = default;
34 
ResolvedTargetDeps(const LabelTargetVector & public_deps,const LabelTargetVector & private_deps,const LabelTargetVector & data_deps)35   ResolvedTargetDeps(const LabelTargetVector& public_deps,
36                      const LabelTargetVector& private_deps,
37                      const LabelTargetVector& data_deps)
38       : public_count_(static_cast<uint32_t>(public_deps.size())),
39         private_count_(static_cast<uint32_t>(private_deps.size())),
40         data_count_(static_cast<uint32_t>(data_deps.size())),
41         deps_(Allocate(public_deps, private_deps, data_deps)) {}
42 
size()43   size_t size() const { return private_count_ + public_count_ + data_count_; }
44 
public_deps()45   base::span<const Target*> public_deps() const {
46     return {deps_.get(), public_count_};
47   }
48 
private_deps()49   base::span<const Target*> private_deps() const {
50     return {deps_.get() + public_count_, private_count_};
51   }
52 
data_deps()53   base::span<const Target*> data_deps() const {
54     return {deps_.get() + private_count_ + public_count_, data_count_};
55   }
56 
linked_deps()57   base::span<const Target*> linked_deps() const {
58     return {deps_.get(), private_count_ + public_count_};
59   }
60 
all_deps()61   base::span<const Target*> all_deps() const {
62     return {deps_.get(), private_count_ + public_count_ + data_count_};
63   }
64 
Allocate(const LabelTargetVector & public_deps,const LabelTargetVector & private_deps,const LabelTargetVector & data_deps)65   static std::unique_ptr<const Target* []> Allocate(
66       const LabelTargetVector& public_deps,
67       const LabelTargetVector& private_deps,
68       const LabelTargetVector& data_deps) {
69     size_t total_size =
70         private_deps.size() + public_deps.size() + data_deps.size();
71     auto result = std::make_unique<const Target*[]>(total_size);
72     const Target** ptr = result.get();
73     for (const auto& pair : public_deps)
74       *ptr++ = pair.ptr;
75     for (const auto& pair : private_deps)
76       *ptr++ = pair.ptr;
77     for (const auto& pair : data_deps)
78       *ptr++ = pair.ptr;
79     return result;
80   }
81 
82   private : uint32_t public_count_ = 0;
83   uint32_t private_count_ = 0;
84   uint32_t data_count_ = 0;
85   std::unique_ptr<const Target*[]> deps_;
86 };
87 
88 #endif  // TOOLS_GN_RESOLVED_TARGET_DEPS_H_
89