diff options
author | Stephen Hines <srhines@google.com> | 2017-02-08 10:45:48 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-02-08 10:45:48 +0000 |
commit | 9826fbe38e2bc35fc6c680cc216dcb993b54d2ff (patch) | |
tree | 87b3a32b13c392939d66fa93105896f5df0736a6 /fdo_scripts/divide_and_merge_profiles.py | |
parent | baba90fd78c18585d22430dc95c748f96ad0c772 (diff) | |
parent | 271389dd3199539c4474c351942f4d4fa975b81b (diff) | |
download | toolchain-utils-9826fbe38e2bc35fc6c680cc216dcb993b54d2ff.tar.gz |
Merge remote-tracking branch 'aosp/mirror-chromium-master' into initial_import am: 870a8df6fc am: 9c6fa5f9e5 am: c5804ce784
am: 271389dd31
Change-Id: I22e657bc86117da9a6a45329a67a21096736da03
Diffstat (limited to 'fdo_scripts/divide_and_merge_profiles.py')
-rwxr-xr-x | fdo_scripts/divide_and_merge_profiles.py | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/fdo_scripts/divide_and_merge_profiles.py b/fdo_scripts/divide_and_merge_profiles.py new file mode 100755 index 00000000..99155852 --- /dev/null +++ b/fdo_scripts/divide_and_merge_profiles.py @@ -0,0 +1,140 @@ +#!/usr/bin/python +# +# Copyright 2011 Google Inc. All Rights Reserved. +"""Script to divide and merge profiles.""" + +import copy +import optparse +import os +import pickle +import re +import sys +import tempfile + +import build_chrome_browser +import lock_machine +import run_tests +from cros_utils import command_executer +from cros_utils import logger + + +class ProfileMerger: + + def __init__(self, inputs, output, chunk_size, merge_program, multipliers): + self._inputs = inputs + self._output = output + self._chunk_size = chunk_size + self._merge_program = merge_program + self._multipliers = multipliers + self._ce = command_executer.GetCommandExecuter() + self._l = logger.GetLogger() + + def _GetFilesSetForInputDir(self, input_dir): + output_file = tempfile.mktemp() + command = "find %s -name '*.gcda' -o -name '*.imports' > %s" % (input_dir, + output_file) + self._ce.RunCommand(command) + files = open(output_file, 'r').read() + files_set = set([]) + for f in files.splitlines(): + stripped_file = f.replace(input_dir, '', 1) + stripped_file = stripped_file.lstrip('/') + files_set.add(stripped_file) + return files_set + + def _PopulateFilesSet(self): + self._files_set = set([]) + for i in self._inputs: + current_files_set = self._GetFilesSetForInputDir(i) + self._files_set.update(current_files_set) + + def _GetSubset(self): + ret = [] + for i in range(self._chunk_size): + if not self._files_set: + break + ret.append(self._files_set.pop()) + return ret + + def _CopyFilesTree(self, input_dir, files, output_dir): + for f in files: + src_file = os.path.join(input_dir, f) + dst_file = os.path.join(output_dir, f) + if not os.path.isdir(os.path.dirname(dst_file)): + command = 'mkdir -p %s' % os.path.dirname(dst_file) + self._ce.RunCommand(command) + command = 'cp %s %s' % (src_file, dst_file) + self._ce.RunCommand(command) + + def _DoChunkMerge(self, current_files): + temp_dirs = [] + for i in self._inputs: + temp_dir = tempfile.mkdtemp() + temp_dirs.append(temp_dir) + self._CopyFilesTree(i, current_files, temp_dir) + # Now do the merge. + command = ('%s --inputs=%s --output=%s' % + (self._merge_program, ','.join(temp_dirs), self._output)) + if self._multipliers: + command = ('%s --multipliers=%s' % (command, self._multipliers)) + ret = self._ce.RunCommand(command) + assert ret == 0, '%s command failed!' % command + for temp_dir in temp_dirs: + command = 'rm -rf %s' % temp_dir + self._ce.RunCommand(command) + + def DoMerge(self): + self._PopulateFilesSet() + while True: + current_files = self._GetSubset() + if not current_files: + break + self._DoChunkMerge(current_files) + + +def Main(argv): + """The main function.""" + # Common initializations + ### command_executer.InitCommandExecuter(True) + command_executer.InitCommandExecuter() + l = logger.GetLogger() + ce = command_executer.GetCommandExecuter() + parser = optparse.OptionParser() + parser.add_option('--inputs', + dest='inputs', + help='Comma-separated input profile directories to merge.') + parser.add_option('--output', dest='output', help='Output profile directory.') + parser.add_option('--chunk_size', + dest='chunk_size', + default='50', + help='Chunk size to divide up the profiles into.') + parser.add_option('--merge_program', + dest='merge_program', + default='/home/xur/bin/profile_merge_v15.par', + help='Merge program to use to do the actual merge.') + parser.add_option('--multipliers', + dest='multipliers', + help='multipliers to use when merging. (optional)') + + options, _ = parser.parse_args(argv) + + if not all([options.inputs, options.output]): + l.LogError('Must supply --inputs and --output') + return 1 + + try: + pm = ProfileMerger( + options.inputs.split(','), options.output, int(options.chunk_size), + options.merge_program, options.multipliers) + pm.DoMerge() + retval = 0 + except: + retval = 1 + finally: + print 'My work is done...' + return retval + + +if __name__ == '__main__': + retval = Main(sys.argv) + sys.exit(retval) |