/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/xml8.py

  • Committer: John Arbash Meinel
  • Date: 2008-12-12 20:06:28 UTC
  • mto: This revision was merged to the branch mainline in revision 3912.
  • Revision ID: john@arbash-meinel.com-20081212200628-xmm9i33jq3d6tsh3
Start moving things around so that the entry cache is passed in.

This has a negligible effect on performance, and means that we can have the
cache lifetime associated with a repository, rather than 'always on'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import cStringIO
18
18
import re
20
20
from bzrlib import (
21
21
    cache_utf8,
22
22
    errors,
 
23
    fifo_cache,
23
24
    inventory,
24
25
    revision as _mod_revision,
25
26
    trace,
26
27
    )
27
 
from bzrlib.xml_serializer import (
28
 
    Element,
29
 
    SubElement,
30
 
    XMLSerializer,
31
 
    escape_invalid_chars,
32
 
    )
33
 
from bzrlib.inventory import InventoryEntry
 
28
from bzrlib.xml_serializer import SubElement, Element, Serializer
 
29
from bzrlib.inventory import ROOT_ID, Inventory, InventoryEntry
34
30
from bzrlib.revision import Revision
35
31
from bzrlib.errors import BzrError
36
32
 
44
40
    "<":"&lt;",
45
41
    ">":"&gt;",
46
42
    }
 
43
_entry_cache = fifo_cache.FIFOCache(10*1024)
47
44
 
48
45
 
49
46
def _ensure_utf8_re():
97
94
    # to check if None, rather than try/KeyError
98
95
    text = _map.get(unicode_or_utf8_str)
99
96
    if text is None:
100
 
        if unicode_or_utf8_str.__class__ is unicode:
 
97
        if unicode_or_utf8_str.__class__ == unicode:
101
98
            # The alternative policy is to do a regular UTF8 encoding
102
99
            # and then escape only XML meta characters.
103
100
            # Performance is equivalent once you use cache_utf8. *However*
133
130
    # This is fairly optimized because we know what cElementTree does, this is
134
131
    # not meant as a generic function for all cases. Because it is possible for
135
132
    # an 8-bit string to not be ascii or valid utf8.
136
 
    if a_str.__class__ is unicode:
 
133
    if a_str.__class__ == unicode:
137
134
        return _encode_utf8(a_str)
138
135
    else:
139
 
        return intern(a_str)
 
136
        return _get_cached_ascii(a_str)
140
137
 
141
138
 
142
139
def _clear_cache():
144
141
    _to_escaped_map.clear()
145
142
 
146
143
 
147
 
class Serializer_v8(XMLSerializer):
 
144
class Serializer_v8(Serializer):
148
145
    """This serialiser adds rich roots.
149
146
 
150
147
    Its revision format number matches its inventory number.
165
162
        """Extension point for subclasses to check during serialisation.
166
163
 
167
164
        :param inv: An inventory about to be serialised, to be checked.
168
 
        :raises: AssertionError if an error has occurred.
 
165
        :raises: AssertionError if an error has occured.
169
166
        """
170
167
        if inv.revision_id is None:
171
 
            raise AssertionError("inv.revision_id is None")
 
168
            raise AssertionError()
172
169
        if inv.root.revision is None:
173
 
            raise AssertionError("inv.root.revision is None")
 
170
            raise AssertionError()
174
171
 
175
172
    def _check_cache_size(self, inv_size, entry_cache):
176
173
        """Check that the entry_cache is large enough.
216
213
 
217
214
    def write_inventory(self, inv, f, working=False):
218
215
        """Write inventory to a file.
219
 
 
 
216
        
220
217
        :param inv: the inventory to write.
221
218
        :param f: the file to write. (May be None if the lines are the desired
222
219
            output).
346
343
            root.set('timezone', str(rev.timezone))
347
344
        root.text = '\n'
348
345
        msg = SubElement(root, 'message')
349
 
        msg.text = escape_invalid_chars(rev.message)[0]
 
346
        msg.text = rev.message
350
347
        msg.tail = '\n'
351
348
        if rev.parent_ids:
352
349
            pelts = SubElement(root, 'parents')
371
368
            prop_elt.tail = '\n'
372
369
        top_elt.tail = '\n'
373
370
 
374
 
    def _unpack_inventory(self, elt, revision_id=None, entry_cache=None,
375
 
                          return_from_cache=False):
 
371
    def _unpack_inventory(self, elt, revision_id=None, entry_cache=None):
376
372
        """Construct from XML Element"""
377
373
        if elt.tag != 'inventory':
378
374
            raise errors.UnexpectedInventoryFormat('Root tag is %r' % elt.tag)
380
376
        if format != self.format_num:
381
377
            raise errors.UnexpectedInventoryFormat('Invalid format version %r'
382
378
                                                   % format)
 
379
        if entry_cache is None:
 
380
            entry_cache = _entry_cache
383
381
        revision_id = elt.get('revision_id')
384
382
        if revision_id is not None:
385
383
            revision_id = cache_utf8.encode(revision_id)
386
384
        inv = inventory.Inventory(root_id=None, revision_id=revision_id)
387
385
        for e in elt:
388
 
            ie = self._unpack_entry(e, entry_cache=entry_cache,
389
 
                                    return_from_cache=return_from_cache)
 
386
            ie = self._unpack_entry(e, entry_cache=entry_cache)
390
387
            inv.add(ie)
391
388
        self._check_cache_size(len(inv), entry_cache)
392
389
        return inv
393
390
 
394
 
    def _unpack_entry(self, elt, entry_cache=None, return_from_cache=False):
 
391
    def _unpack_entry(self, elt, entry_cache=None):
395
392
        elt_get = elt.get
396
393
        file_id = elt_get('file_id')
397
394
        revision = elt_get('revision')
429
426
        if entry_cache is not None and revision is not None:
430
427
            key = (file_id, revision)
431
428
            try:
432
 
                # We copy it, because some operations may mutate it
 
429
                # We copy it, because some operatations may mutate it
433
430
                cached_ie = entry_cache[key]
434
431
            except KeyError:
435
432
                pass
436
433
            else:
437
434
                # Only copying directory entries drops us 2.85s => 2.35s
438
 
                if return_from_cache:
439
 
                    if cached_ie.kind == 'directory':
440
 
                        return cached_ie.copy()
441
 
                    return cached_ie
 
435
                # if cached_ie.kind == 'directory':
 
436
                #     return cached_ie.copy()
 
437
                # return cached_ie
442
438
                return cached_ie.copy()
443
439
 
444
440
        kind = elt.tag