~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/store/weave.py

[merge] jam-integration

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
# files whose id differs only in case.  That should probably be forbidden.
21
21
 
22
22
 
 
23
import errno
 
24
import os
23
25
from cStringIO import StringIO
24
 
import os
25
 
import errno
 
26
import urllib
26
27
 
27
28
from bzrlib.weavefile import read_weave, write_weave_v5
28
29
from bzrlib.weave import Weave
39
40
    """
40
41
    FILE_SUFFIX = '.weave'
41
42
 
42
 
    def __init__(self, transport, prefixed=False, precious=False):
43
 
        self._transport = transport
44
 
        self._prefixed = prefixed
 
43
    def __init__(self, transport, prefixed=False, precious=False,
 
44
                 dir_mode=None, file_mode=None):
 
45
        super(WeaveStore, self).__init__(transport,
 
46
                dir_mode=dir_mode, file_mode=file_mode,
 
47
                prefixed=prefixed, compressed=False)
45
48
        self._precious = precious
46
49
 
47
50
    def filename(self, file_id):
48
51
        """Return the path relative to the transport root."""
49
52
        if self._prefixed:
50
 
            return hash_prefix(file_id) + file_id + WeaveStore.FILE_SUFFIX
 
53
            return hash_prefix(file_id) + urllib.quote(file_id) + WeaveStore.FILE_SUFFIX
51
54
        else:
52
 
            return file_id + WeaveStore.FILE_SUFFIX
 
55
            return urllib.quote(file_id) + WeaveStore.FILE_SUFFIX
53
56
 
54
57
    def __iter__(self):
55
58
        l = len(WeaveStore.FILE_SUFFIX)
56
 
        for relpath, st in self._iter_relpaths():
 
59
        for relpath in self._iter_files_recursive():
57
60
            if relpath.endswith(WeaveStore.FILE_SUFFIX):
58
61
                yield os.path.basename(relpath[:-l])
59
62
 
60
 
    def __contains__(self, fileid):
61
 
        """"""
 
63
    def has_id(self, fileid):
62
64
        return self._transport.has(self.filename(fileid))
63
65
 
64
66
    def _get(self, file_id):
67
69
    def _put(self, file_id, f):
68
70
        if self._prefixed:
69
71
            try:
70
 
                self._transport.mkdir(hash_prefix(file_id))
 
72
                self._transport.mkdir(hash_prefix(file_id), mode=self._dir_mode)
71
73
            except FileExists:
72
74
                pass
73
 
        return self._transport.put(self.filename(file_id), f)
 
75
        return self._transport.put(self.filename(file_id), f, mode=self._file_mode)
74
76
 
75
77
    def get_weave(self, file_id, transaction):
76
78
        weave = transaction.map.find_weave(file_id)
80
82
        w = read_weave(self._get(file_id))
81
83
        transaction.map.add_weave(file_id, w)
82
84
        transaction.register_clean(w, precious=self._precious)
 
85
        # TODO: jam 20051219 This should check if there is a prelude
 
86
        #       which is already cached, and if so, should remove it
 
87
        #       But transaction doesn't seem to have a 'remove'
 
88
        #       One workaround would be to re-add the object with
 
89
        #       the PRELUDE marker.
 
90
        return w
 
91
 
 
92
    def get_weave_prelude(self, file_id, transaction):
 
93
        weave_id = file_id
 
94
        weave = transaction.map.find_weave(weave_id)
 
95
        if weave:
 
96
            mutter("cache hit in %s for %s", self, weave_id)
 
97
            return weave
 
98
        # We want transactions to also cache preludes if that
 
99
        # is all that we are loading. So we need a unique
 
100
        # identifier, so that someone who wants the whole text
 
101
        # won't get just the prelude
 
102
        weave_id = 'PRELUDE-' + file_id
 
103
        weave = transaction.map.find_weave(weave_id)
 
104
        if weave:
 
105
            mutter("cache hit in %s for %s", self, weave_id)
 
106
            return weave
 
107
        w = read_weave(self._get(file_id), prelude=True)
 
108
        transaction.map.add_weave(weave_id, w)
 
109
        transaction.register_clean(w, precious=self._precious)
83
110
        return w
84
111
 
85
112
    def get_lines(self, file_id, rev_id, transaction):
89
116
        w = self.get_weave(file_id, transaction)
90
117
        return w.get(w.lookup(rev_id))
91
118
    
 
119
    def get_weave_prelude_or_empty(self, file_id, transaction):
 
120
        """cheap version that reads the prelude but not the lines
 
121
        """
 
122
        try:
 
123
            return self.get_weave_prelude(file_id, transaction)
 
124
        except NoSuchFile:
 
125
            # We can cache here, because we know that there
 
126
            # is no complete object, since we got NoSuchFile
 
127
            weave = Weave(weave_name=file_id)
 
128
            transaction.map.add_weave(file_id, weave)
 
129
            transaction.register_clean(weave, precious=self._precious)
 
130
            return weave
 
131
 
92
132
    def get_weave_or_empty(self, file_id, transaction):
93
133
        """Return a weave, or an empty one if it doesn't exist.""" 
94
134
        try: