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