@@ -280,7 +280,10 @@ class Rollup {
280280 CreateRows (row, base, options, true );
281281 }
282282
283- void SetFilterRegex (const ReImpl* regex) { filter_regex_ = regex; }
283+ void SetFilterRegex (const ReImpl* regex_include, const ReImpl* regex_exclude) {
284+ filter_regex_include_ = regex_include;
285+ filter_regex_exclude_ = regex_exclude;
286+ }
284287
285288 // Add the values in "other" from this.
286289 void Add (const Rollup& other) {
@@ -316,7 +319,8 @@ class Rollup {
316319 int64_t filtered_vm_total_ = 0 ;
317320 int64_t filtered_file_total_ = 0 ;
318321
319- const ReImpl* filter_regex_ = nullptr ;
322+ const ReImpl* filter_regex_include_ = nullptr ;
323+ const ReImpl* filter_regex_exclude_ = nullptr ;
320324
321325 // Putting Rollup by value seems to work on some compilers/libs but not
322326 // others.
@@ -335,20 +339,33 @@ class Rollup {
335339 // If there are more entries names[i+1, i+2, etc] add them to sub-rollups.
336340 void AddInternal (const std::vector<std::string>& names, size_t i,
337341 uint64_t size, bool is_vmsize) {
338- if (filter_regex_ != nullptr ) {
342+ if (filter_regex_include_ != nullptr || filter_regex_exclude_ != nullptr ) {
339343 // filter_regex_ is only set in the root rollup, which checks the full
340344 // label hierarchy for a match to determine whether a region should be
341345 // considered.
342- bool any_matched = false ;
346+ bool exclude = false ;
347+ if (filter_regex_include_ != nullptr ) {
348+ bool any_matched = false ;
349+
350+ for (const auto & name : names) {
351+ if (ReImpl::PartialMatch (name, *filter_regex_include_)) {
352+ any_matched = true ;
353+ break ;
354+ }
355+ }
356+ exclude = !any_matched;
357+ }
343358
344- for (const auto & name : names) {
345- if (ReImpl::PartialMatch (name, *filter_regex_)) {
346- any_matched = true ;
347- break ;
359+ if (!exclude && filter_regex_exclude_ != nullptr ) {
360+ for (const auto & name : names) {
361+ if (ReImpl::PartialMatch (name, *filter_regex_exclude_)) {
362+ exclude = true ;
363+ break ;
364+ }
348365 }
349366 }
350367
351- if (!any_matched ) {
368+ if (exclude ) {
352369 // Ignore this region in the rollup and don't visit sub-rollups.
353370 if (is_vmsize) {
354371 CheckedAdd (&filtered_vm_total_, size);
@@ -1810,13 +1827,17 @@ void Bloaty::ScanAndRollupFiles(const std::vector<std::string>& filenames,
18101827 std::vector<std::thread> threads (num_threads);
18111828 ThreadSafeIterIndex index (filenames.size ());
18121829
1813- std::unique_ptr<ReImpl> regex = nullptr ;
1830+ std::unique_ptr<ReImpl> regex_include = nullptr ;
1831+ std::unique_ptr<ReImpl> regex_exclude = nullptr ;
18141832 if (options_.has_source_filter ()) {
1815- regex = absl::make_unique<ReImpl>(options_.source_filter ());
1833+ regex_include = absl::make_unique<ReImpl>(options_.source_filter ());
1834+ }
1835+ if (options_.has_exclude_source_filter ()) {
1836+ regex_exclude = absl::make_unique<ReImpl>(options_.exclude_source_filter ());
18161837 }
18171838
18181839 for (int i = 0 ; i < num_threads; i++) {
1819- thread_data[i].rollup .SetFilterRegex (regex .get ());
1840+ thread_data[i].rollup .SetFilterRegex (regex_include. get (), regex_exclude .get ());
18201841
18211842 threads[i] = std::thread (
18221843 [this , &index, &filenames](PerThreadData* data) {
@@ -1960,6 +1981,10 @@ USAGE: bloaty [OPTION]... FILE... [-- BASE_FILE...]
19601981 --list-sources Show a list of available sources and exit.
19611982 --source-filter=PATTERN
19621983 Only show keys with names matching this pattern.
1984+ --exclude-source-filter=PATTERN
1985+ Exclude keys with names matching this pattern.
1986+ When both --source-filter and --exclude-source-filter
1987+ match the same data, the data will be excluded.
19631988
19641989Options for debugging Bloaty:
19651990
@@ -2159,6 +2184,8 @@ bool DoParseOptions(bool skip_unknown, int* argc, char** argv[],
21592184 }
21602185 } else if (args.TryParseOption (" --source-filter" , &option)) {
21612186 options->set_source_filter (std::string (option));
2187+ } else if (args.TryParseOption (" --exclude-source-filter" , &option)) {
2188+ options->set_exclude_source_filter (std::string (option));
21622189 } else if (args.TryParseFlag (" -v" )) {
21632190 options->set_verbose_level (1 );
21642191 } else if (args.TryParseFlag (" -vv" )) {
@@ -2264,7 +2291,14 @@ void BloatyDoMain(const Options& options, const InputFileFactory& file_factory,
22642291 if (options.has_source_filter ()) {
22652292 ReImpl re (options.source_filter ());
22662293 if (!re.ok ()) {
2267- THROW (" invalid regex for source_filter" );
2294+ THROW (" invalid regex for --source-filter" );
2295+ }
2296+ }
2297+
2298+ if (options.has_exclude_source_filter ()) {
2299+ ReImpl re (options.exclude_source_filter ());
2300+ if (!re.ok ()) {
2301+ THROW (" invalid regex for --exclude-source-filter" );
22682302 }
22692303 }
22702304
0 commit comments