~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tuned_gzip.py

  • Committer: Vincent Ladeuil
  • Date: 2009-06-22 12:52:39 UTC
  • mto: (4471.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 4472.
  • Revision ID: v.ladeuil+lp@free.fr-20090622125239-kabo9smxt9c3vnir
Use a consistent scheme for naming pyrex source files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
#
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
"""Bzrlib specific gzip tunings. We plan to feed these to the upstream gzip."""
19
19
 
21
21
 
22
22
# make GzipFile faster:
23
23
import gzip
24
 
from gzip import U32, LOWU32, FEXTRA, FCOMMENT, FNAME, FHCRC
 
24
from gzip import FEXTRA, FCOMMENT, FNAME, FHCRC
25
25
import sys
26
26
import struct
27
27
import zlib
32
32
__all__ = ["GzipFile", "bytes_to_gzip"]
33
33
 
34
34
 
 
35
def U32(i):
 
36
    """Return i as an unsigned integer, assuming it fits in 32 bits.
 
37
 
 
38
    If it's >= 2GB when viewed as a 32-bit unsigned int, return a long.
 
39
    """
 
40
    if i < 0:
 
41
        i += 1L << 32
 
42
    return i
 
43
 
 
44
 
 
45
def LOWU32(i):
 
46
    """Return the low-order 32 bits of an int, as a non-negative int."""
 
47
    return i & 0xFFFFFFFFL
 
48
 
 
49
 
35
50
def bytes_to_gzip(bytes, factory=zlib.compressobj,
36
51
    level=zlib.Z_DEFAULT_COMPRESSION, method=zlib.DEFLATED,
37
52
    width=-zlib.MAX_WBITS, mem=zlib.DEF_MEM_LEVEL,
99
114
        """A tuned version of gzip._write_gzip_header
100
115
 
101
116
        We have some extra constrains that plain Gzip does not.
102
 
        1) We want to write the whole blob at once. rather than multiple 
 
117
        1) We want to write the whole blob at once. rather than multiple
103
118
           calls to fileobj.write().
104
119
        2) We never have a filename
105
120
        3) We don't care about the time
121
136
 
122
137
    def _read(self, size=1024):
123
138
        # various optimisations:
124
 
        # reduces lsprof count from 2500 to 
 
139
        # reduces lsprof count from 2500 to
125
140
        # 8337 calls in 1272, 365 internal
126
141
        if self.fileobj is None:
127
142
            raise EOFError, "Reached EOF"
192
207
        """tuned to reduce function calls and eliminate file seeking:
193
208
        pass 1:
194
209
        reduces lsprof count from 800 to 288
195
 
        4168 in 296 
 
210
        4168 in 296
196
211
        avoid U32 call by using struct format L
197
212
        4168 in 200
198
213
        """
199
 
        # We've read to the end of the file, so we should have 8 bytes of 
 
214
        # We've read to the end of the file, so we should have 8 bytes of
200
215
        # unused data in the decompressor. If we don't, there is a corrupt file.
201
216
        # We use these 8 bytes to calculate the CRC and the recorded file size.
202
217
        # We then check the that the computed CRC and size of the
213
228
 
214
229
    def _read_gzip_header(self, bytes=None):
215
230
        """Supply bytes if the minimum header size is already read.
216
 
        
 
231
 
217
232
        :param bytes: 10 bytes of header data.
218
233
        """
219
234
        """starting cost: 300 in 3998
256
271
 
257
272
    def readline(self, size=-1):
258
273
        """Tuned to remove buffer length calls in _unread and...
259
 
        
 
274
 
260
275
        also removes multiple len(c) calls, inlines _unread,
261
276
        total savings - lsprof 5800 to 5300
262
277
        phase 2:
266
281
        leading to a drop to:
267
282
        4168 calls in 1977
268
283
        4168 call to read() in 1646
269
 
        - i.e. just reduced the function call overhead. May be worth 
 
284
        - i.e. just reduced the function call overhead. May be worth
270
285
          keeping.
271
286
        """
272
287
        if size < 0: size = sys.maxint
314
329
        # to :
315
330
        # 4168 calls in 417.
316
331
        # Negative numbers result in reading all the lines
317
 
        
 
332
 
318
333
        # python's gzip routine uses sizehint. This is a more efficient way
319
334
        # than python uses to honor it. But it is even more efficient to
320
335
        # just read the entire thing and use cStringIO to split into lines.
327
342
 
328
343
    def _unread(self, buf, len_buf=None):
329
344
        """tuned to remove unneeded len calls.
330
 
        
 
345
 
331
346
        because this is such an inner routine in readline, and readline is
332
347
        in many inner loops, this has been inlined into readline().
333
348
 
334
349
        The len_buf parameter combined with the reduction in len calls dropped
335
 
        the lsprof ms count for this routine on my test data from 800 to 200 - 
 
350
        the lsprof ms count for this routine on my test data from 800 to 200 -
336
351
        a 75% saving.
337
352
        """
338
353
        if len_buf is None:
356
371
            self.offset += data_len
357
372
 
358
373
    def writelines(self, lines):
359
 
        # profiling indicated a significant overhead 
 
374
        # profiling indicated a significant overhead
360
375
        # calling write for each line.
361
376
        # this batch call is a lot faster :).
362
377
        # (4 seconds to 1 seconds for the sample upgrades I was testing).