~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/benchmarks/tree_creator/kernel_like.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-08-02 23:49:34 UTC
  • mfrom: (5362.1.1 merge-2.2-into-trunk)
  • Revision ID: pqm@pqm.ubuntu.com-20100802234934-d963xmqwx5gzevr0
(Andrew Bennetts) Merge 2.2 branch back into trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
2
 
#
3
 
# This program is free software; you can redistribute it and/or modify
4
 
# it under the terms of the GNU General Public License as published by
5
 
# the Free Software Foundation; either version 2 of the License, or
6
 
# (at your option) any later version.
7
 
#
8
 
# This program is distributed in the hope that it will be useful,
9
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
# GNU General Public License for more details.
12
 
#
13
 
# You should have received a copy of the GNU General Public License
14
 
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
"""Tree creators for kernel-like trees"""
18
 
 
19
 
import errno
20
 
import os
21
 
 
22
 
from bzrlib import (
23
 
    bzrdir,
24
 
    osutils,
25
 
    workingtree,
26
 
    xml5,
27
 
    )
28
 
 
29
 
from bzrlib.benchmarks.tree_creator import TreeCreator
30
 
 
31
 
 
32
 
class KernelLikeTreeCreator(TreeCreator):
33
 
    """Create a basic tree with ~10k unversioned files"""
34
 
 
35
 
    def __init__(self, test, link_working=False, url=None):
36
 
        super(KernelLikeTreeCreator, self).__init__(test,
37
 
            tree_name='kernel_like_tree',
38
 
            link_working=link_working,
39
 
            link_bzr=False)
40
 
 
41
 
        self._url = url
42
 
 
43
 
    def create(self, root):
44
 
        """Create all the kernel files in the given location.
45
 
 
46
 
        This is overloaded for compatibility reasons.
47
 
        """
48
 
        if self._url is not None:
49
 
            b = bzrdir.BzrDir.create_branch_convenience(self._url)
50
 
            d = bzrdir.BzrDir.create(root)
51
 
            bzrlib.branch.BranchReferenceFormat().initialize(d,
52
 
                target_branch=b)
53
 
            tree = d.create_workingtree()
54
 
        else:
55
 
            tree = bzrdir.BzrDir.create_standalone_workingtree(root)
56
 
 
57
 
        if not self._link_working or not self.is_caching_enabled():
58
 
            # Turns out that 'shutil.copytree()' is no faster than
59
 
            # just creating them. Probably the python overhead.
60
 
            # Plain _make_kernel_files takes 3-5s
61
 
            # cp -a takes 3s
62
 
            # using hardlinks takes < 1s.
63
 
            self._create_tree(root=root, in_cache=False)
64
 
            return tree
65
 
 
66
 
        self.ensure_cached()
67
 
        cache_dir = self._get_cache_dir()
68
 
        osutils.copy_tree(cache_dir, root,
69
 
                          handlers={'file':os.link})
70
 
        return tree
71
 
 
72
 
    def _create_tree(self, root, in_cache=False):
73
 
        # a kernel tree has ~10000 and 500 directory, with most files around
74
 
        # 3-4 levels deep.
75
 
        # we simulate this by three levels of dirs named 0-7, givin 512 dirs,
76
 
        # and 20 files each.
77
 
        files = []
78
 
        for outer in range(8):
79
 
            files.append("%s/" % outer)
80
 
            for middle in range(8):
81
 
                files.append("%s/%s/" % (outer, middle))
82
 
                for inner in range(8):
83
 
                    prefix = "%s/%s/%s/" % (outer, middle, inner)
84
 
                    files.append(prefix)
85
 
                    files.extend([prefix + str(foo) for foo in range(20)])
86
 
        cwd = osutils.getcwd()
87
 
        try:
88
 
            os.mkdir(root)
89
 
        except OSError, e:
90
 
            if e.errno not in (errno.EEXIST,):
91
 
                raise
92
 
        os.chdir(root)
93
 
        self._test.build_tree(files)
94
 
        os.chdir(cwd)
95
 
        if in_cache:
96
 
            self._protect_files(root)
97
 
 
98
 
 
99
 
class KernelLikeAddedTreeCreator(TreeCreator):
100
 
    """Create a tree with ~10k versioned but not committed files"""
101
 
 
102
 
    def __init__(self, test, link_working=False, hot_cache=True):
103
 
        super(KernelLikeAddedTreeCreator, self).__init__(test,
104
 
            tree_name='kernel_like_added_tree',
105
 
            link_working=link_working,
106
 
            link_bzr=False,
107
 
            hot_cache=hot_cache)
108
 
 
109
 
    def _create_tree(self, root, in_cache=False):
110
 
        """Create a kernel-like tree with the all files added
111
 
 
112
 
        :param root: The root directory to create the files
113
 
        :param in_cache: Is this being created in the cache dir?
114
 
        """
115
 
        kernel_creator = KernelLikeTreeCreator(self._test,
116
 
                                               link_working=in_cache)
117
 
        tree = kernel_creator.create(root=root)
118
 
 
119
 
        # Add everything to it
120
 
        tree.lock_write()
121
 
        try:
122
 
            tree.smart_add([root], recurse=True, save=True)
123
 
            if in_cache:
124
 
                self._protect_files(root+'/.bzr')
125
 
        finally:
126
 
            tree.unlock()
127
 
        return tree
128
 
 
129
 
 
130
 
class KernelLikeCommittedTreeCreator(TreeCreator):
131
 
    """Create a tree with ~10K files, and a single commit adding all of them"""
132
 
 
133
 
    def __init__(self, test, link_working=False, link_bzr=False,
134
 
                 hot_cache=True):
135
 
        super(KernelLikeCommittedTreeCreator, self).__init__(test,
136
 
            tree_name='kernel_like_committed_tree',
137
 
            link_working=link_working,
138
 
            link_bzr=link_bzr,
139
 
            hot_cache=hot_cache)
140
 
 
141
 
    def _create_tree(self, root, in_cache=False):
142
 
        """Create a kernel-like tree with all files committed
143
 
 
144
 
        :param root: The root directory to create the files
145
 
        :param in_cache: Is this being created in the cache dir?
146
 
        """
147
 
        kernel_creator = KernelLikeAddedTreeCreator(self._test,
148
 
                                                    link_working=in_cache,
149
 
                                                    hot_cache=(not in_cache))
150
 
        tree = kernel_creator.create(root=root)
151
 
        tree.commit('first post', rev_id='r1')
152
 
 
153
 
        if in_cache:
154
 
            self._protect_files(root+'/.bzr')
155
 
        return tree
156
 
 
157
 
 
158
 
class KernelLikeInventoryCreator(TreeCreator):
159
 
    """Return just the memory representation of a committed kernel-like tree"""
160
 
 
161
 
    def __init__(self, test):
162
 
        super(KernelLikeInventoryCreator, self).__init__(test,
163
 
            tree_name='kernel_like_inventory',
164
 
            link_working=True,
165
 
            link_bzr=True,
166
 
            hot_cache=True)
167
 
 
168
 
    def ensure_cached(self):
169
 
        """Make sure we have a cached version of the kernel-like inventory"""
170
 
        cache_dir = self._get_cache_dir()
171
 
        if cache_dir is None:
172
 
            return
173
 
 
174
 
        if self.is_cached():
175
 
            return
176
 
 
177
 
        committed_creator = KernelLikeCommittedTreeCreator(self._test,
178
 
                                                           link_working=True,
179
 
                                                           link_bzr=True,
180
 
                                                           hot_cache=False)
181
 
        committed_creator.ensure_cached()
182
 
        committed_cache_dir = committed_creator._get_cache_dir()
183
 
        committed_tree = workingtree.WorkingTree.open(committed_cache_dir)
184
 
        rev_tree = committed_tree.basis_tree()
185
 
        os.mkdir(cache_dir)
186
 
        f = open(cache_dir+'/inventory', 'wb')
187
 
        try:
188
 
            xml5.serializer_v5.write_inventory(rev_tree.inventory, f)
189
 
        finally:
190
 
            f.close()
191
 
 
192
 
    def create(self, root=None):
193
 
        """Create a kernel like inventory
194
 
 
195
 
        :param root: Exists to mimic the base class, but this class
196
 
            returns only an in-memory Inventory, so it should always be None.
197
 
        :return: An Inventory object.
198
 
        """
199
 
        cache_dir = self._get_cache_dir()
200
 
        if cache_dir is None:
201
 
            return self._create_and_return()
202
 
 
203
 
        self.ensure_cached()
204
 
        return self._open_cached(cache_dir)
205
 
 
206
 
    def _create_and_return(self):
207
 
        """Create a kernel-like tree, and return its inventory"""
208
 
        creator = KernelLikeCommittedTreeCreator(self._test,
209
 
                                                 link_working=True,
210
 
                                                 link_bzr=True,
211
 
                                                 hot_cache=False)
212
 
        tree = creator.create('.')
213
 
        basis = tree.basis_tree()
214
 
        basis.lock_read()
215
 
        try:
216
 
            return basis.inventory
217
 
        finally:
218
 
            basis.unlock()
219
 
 
220
 
    def _open_cached(self, cache_dir):
221
 
        f = open(cache_dir + '/inventory', 'rb')
222
 
        try:
223
 
            return xml5.serializer_v5.read_inventory(f)
224
 
        finally:
225
 
            f.close()