~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/benchmarks/__init__.py

  • Committer: John Arbash Meinel
  • Date: 2006-08-07 19:33:37 UTC
  • mto: (1908.4.6 commit-perf)
  • mto: This revision was merged to the branch mainline in revision 1923.
  • Revision ID: john@arbash-meinel.com-20060807193337-a1f1a022c7e06940
Allow caching basic kernel-like trees

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
"""Benchmark test suite for bzr."""
19
19
 
20
 
from bzrlib import bzrdir, plugin
 
20
import os
 
21
import shutil
 
22
 
 
23
from bzrlib import (
 
24
    add,
 
25
    bzrdir,
 
26
    osutils,
 
27
    plugin,
 
28
    workingtree,
 
29
    )
21
30
from bzrlib.tests.TestUtil import TestLoader
22
31
from bzrlib.tests.blackbox import ExternalBase
23
32
 
24
33
 
25
34
class Benchmark(ExternalBase):
26
35
 
27
 
    def make_kernel_like_tree(self, url=None):
 
36
    _cached_kernel_like_tree = None
 
37
    _cached_kernel_like_added_tree = None
 
38
 
 
39
    def make_kernel_like_tree(self, url=None, root='.',
 
40
                              hardlink_working=False):
28
41
        """Setup a temporary tree roughly like a kernel tree.
29
42
        
30
43
        :param url: Creat the kernel like tree as a lightweight checkout
31
44
        of a new branch created at url.
 
45
        :param hardlink_working: instead of creating a new copy of all files
 
46
            just hardlink the working tree. Tests must request this, because
 
47
            they must break links if they want to change the files
32
48
        """
 
49
        if url is not None:
 
50
            b = bzrdir.BzrDir.create_branch_convenience(url)
 
51
            d = bzrdir.BzrDir.create(root)
 
52
            bzrlib.branch.BranchReferenceFormat().initialize(d, b)
 
53
            tree = d.create_workingtree()
 
54
        else:
 
55
            tree = bzrdir.BzrDir.create_standalone_workingtree(root)
 
56
 
 
57
        self._link_or_copy_kernel_files(root=root, do_link=hardlink_working)
 
58
        return tree
 
59
 
 
60
    def _make_kernel_files(self, root='.'):
33
61
        # a kernel tree has ~10000 and 500 directory, with most files around 
34
62
        # 3-4 levels deep. 
35
63
        # we simulate this by three levels of dirs named 0-7, givin 512 dirs,
36
64
        # and 20 files each.
37
 
        if url is not None:
38
 
            b = bzrdir.BzrDir.create_branch_convenience(url)
39
 
            d = bzrdir.BzrDir.create('.')
40
 
            bzrlib.branch.BranchReferenceFormat().initialize(d, b)
41
 
            d.create_workingtree()
42
 
        else:
43
 
            self.run_bzr('init')
44
65
        files = []
45
66
        for outer in range(8):
46
67
            files.append("%s/" % outer)
50
71
                    prefix = "%s/%s/%s/" % (outer, middle, inner)
51
72
                    files.append(prefix)
52
73
                    files.extend([prefix + str(foo) for foo in range(20)])
 
74
        cwd = osutils.getcwd()
 
75
        os.chdir(root)
53
76
        self.build_tree(files)
 
77
        os.chdir(cwd)
 
78
 
 
79
    def _link_or_copy_kernel_files(self, root, do_link=True):
 
80
        """Hardlink the kernel files from the cached location.
 
81
 
 
82
        If the platform doesn't correctly support hardlinking files, it
 
83
        reverts to just creating new ones.
 
84
        """
 
85
 
 
86
        if not osutils.hardlinks_good() or not do_link:
 
87
            # Turns out that 'shutil.copytree()' is no faster than
 
88
            # just creating them. Probably the python overhead.
 
89
            # Plain _make_kernel_files takes 5s
 
90
            # cp -a takes 3s
 
91
            # using hardlinks takes < 1s.
 
92
            self._make_kernel_files(root=root)
 
93
            return
 
94
 
 
95
        if Benchmark._cached_kernel_like_tree is None:
 
96
            cache_dir = osutils.pathjoin(self.TEST_ROOT,
 
97
                                         'cached_kernel_like_tree')
 
98
            os.mkdir(cache_dir)
 
99
            self._make_kernel_files(root=cache_dir)
 
100
            Benchmark._cached_kernel_like_tree = cache_dir
 
101
 
 
102
        # Hardlinking the target directory is *much* faster (7s => <1s).
 
103
        osutils.copy_tree(Benchmark._cached_kernel_like_tree, root,
 
104
                          handlers={'file':os.link})
 
105
 
 
106
    def make_kernel_like_added_tree(self, root='.',
 
107
                                    hardlink_working=True):
 
108
        """Make a kernel like tree, with all files added
 
109
 
 
110
        :param root: Where to create the files
 
111
        :param hardlink_working: Instead of copying all of the working tree
 
112
            files, just hardlink them to the cached files. Tests can unlink
 
113
            files that they will change.
 
114
        """
 
115
        if Benchmark._cached_kernel_like_added_tree is None:
 
116
            cache_dir = osutils.pathjoin(self.TEST_ROOT,
 
117
                                         'cached_kernel_like_added_tree')
 
118
            # Get a basic tree with working files
 
119
            tree = self.make_kernel_like_tree(root=cache_dir,
 
120
                                              hardlink_working=True)
 
121
            # Add everything to it
 
122
            add.smart_add_tree(tree, [cache_dir], recurse=True, save=True)
 
123
            Benchmark._cached_kernel_like_added_tree = cache_dir
 
124
 
 
125
        # Now we have a cached tree, just copy it
 
126
        handlers = {} # Copy all files
 
127
        if osutils.hardlinks_good() and hardlink_working:
 
128
            # Hardlink only working files (not files underneath .bzr)
 
129
            def file_handler(source, dest):
 
130
                if '.bzr/' in source:
 
131
                    shutil.copy2(source, dest)
 
132
                else:
 
133
                    os.link(source, dest)
 
134
            handlers = {'file':file_handler}
 
135
 
 
136
        osutils.copy_tree(Benchmark._cached_kernel_like_added_tree, root,
 
137
                          handlers=handlers)
 
138
        return workingtree.WorkingTree.open(root)
54
139
 
55
140
    def make_many_commit_tree(self, directory_name='.'):
56
141
        """Create a tree with many commits.