~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_groupcompress_pyx.pyx

  • Committer: John Arbash Meinel
  • Date: 2009-11-06 18:05:03 UTC
  • mto: This revision was merged to the branch mainline in revision 4814.
  • Revision ID: john@arbash-meinel.com-20091106180503-q3hcg1nxmut5b2cb
Stop holding the gil while extracting data.

Previous experience has shown that we don't really spend a lot
of time here, but there isn't any reason to hold the lock while
we do it anyway.

Performance testing has shown that for bzr operations 'with nogil'
doesn't really do much, which was generally expected. Any variation
observed is within the noise margins.

This is mostly about 'the right thing to do', and potential
future work where we may actually use threads.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
cdef extern from *:
33
33
    ctypedef unsigned long size_t
34
 
    void * malloc(size_t)
35
 
    void * realloc(void *, size_t)
36
 
    void free(void *)
37
 
    void memcpy(void *, void *, size_t)
 
34
    void * malloc(size_t) nogil
 
35
    void * realloc(void *, size_t) nogil
 
36
    void free(void *) nogil
 
37
    void memcpy(void *, void *, size_t) nogil
38
38
 
39
39
 
40
40
cdef extern from "delta.h":
329
329
    cdef unsigned char *dst_buf, *out, cmd
330
330
    cdef Py_ssize_t size
331
331
    cdef unsigned int cp_off, cp_size
 
332
    cdef int failed
332
333
 
333
334
    data = <unsigned char *>delta
334
335
    top = data + delta_size
338
339
    result = PyString_FromStringAndSize(NULL, size)
339
340
    dst_buf = <unsigned char*>PyString_AS_STRING(result)
340
341
 
341
 
    out = dst_buf
342
 
    while (data < top):
343
 
        cmd = data[0]
344
 
        data = data + 1
345
 
        if (cmd & 0x80):
346
 
            # Copy instruction
347
 
            data = _decode_copy_instruction(data, cmd, &cp_off, &cp_size)
348
 
            if (cp_off + cp_size < cp_size or
349
 
                cp_off + cp_size > source_size or
350
 
                cp_size > size):
351
 
                raise RuntimeError('Something wrong with:'
352
 
                    ' cp_off = %s, cp_size = %s'
353
 
                    ' source_size = %s, size = %s'
354
 
                    % (cp_off, cp_size, source_size, size))
355
 
            memcpy(out, source + cp_off, cp_size)
356
 
            out = out + cp_size
357
 
            size = size - cp_size
358
 
        else:
359
 
            # Insert instruction
360
 
            if cmd == 0:
361
 
                # cmd == 0 is reserved for future encoding
362
 
                # extensions. In the mean time we must fail when
363
 
                # encountering them (might be data corruption).
364
 
                raise RuntimeError('Got delta opcode: 0, not supported')
365
 
            if (cmd > size):
366
 
                raise RuntimeError('Insert instruction longer than remaining'
367
 
                    ' bytes: %d > %d' % (cmd, size))
368
 
            memcpy(out, data, cmd)
369
 
            out = out + cmd
370
 
            data = data + cmd
371
 
            size = size - cmd
 
342
    failed = 0
 
343
    with nogil:
 
344
        out = dst_buf
 
345
        while (data < top):
 
346
            cmd = data[0]
 
347
            data = data + 1
 
348
            if (cmd & 0x80):
 
349
                # Copy instruction
 
350
                data = _decode_copy_instruction(data, cmd, &cp_off, &cp_size)
 
351
                if (cp_off + cp_size < cp_size or
 
352
                    cp_off + cp_size > source_size or
 
353
                    cp_size > size):
 
354
                    failed = 1
 
355
                    break
 
356
                memcpy(out, source + cp_off, cp_size)
 
357
                out = out + cp_size
 
358
                size = size - cp_size
 
359
            else:
 
360
                # Insert instruction
 
361
                if cmd == 0:
 
362
                    # cmd == 0 is reserved for future encoding
 
363
                    # extensions. In the mean time we must fail when
 
364
                    # encountering them (might be data corruption).
 
365
                    failed = 2
 
366
                    break
 
367
                if cmd > size:
 
368
                    failed = 3
 
369
                    break
 
370
                memcpy(out, data, cmd)
 
371
                out = out + cmd
 
372
                data = data + cmd
 
373
                size = size - cmd
 
374
    if failed:
 
375
        if failed == 1:
 
376
            raise ValueError('Something wrong with:'
 
377
                ' cp_off = %s, cp_size = %s'
 
378
                ' source_size = %s, size = %s'
 
379
                % (cp_off, cp_size, source_size, size))
 
380
        elif failed == 2:
 
381
            raise ValueError('Got delta opcode: 0, not supported')
 
382
        elif failed == 3:
 
383
            raise ValueError('Insert instruction longer than remaining'
 
384
                ' bytes: %d > %d' % (cmd, size))
372
385
 
373
386
    # sanity check
374
387
    if (data != top or size != 0):