~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_groupcompress_pyx.pyx

  • Committer: Vincent Ladeuil
  • Date: 2010-01-25 15:55:48 UTC
  • mto: (4985.1.4 add-attr-cleanup)
  • mto: This revision was merged to the branch mainline in revision 4988.
  • Revision ID: v.ladeuil+lp@free.fr-20100125155548-0l352pujvt5bzl5e
Deploy addAttrCleanup on the whole test suite.

Several use case worth mentioning:

- setting a module or any other object attribute is the majority
by far. In some cases the setting itself is deferred but most of
the time we want to set at the same time we add the cleanup.

- there multiple occurrences of protecting hooks or ui factory
which are now useless (the test framework takes care of that now),

- there was some lambda uses that can now be avoided.

That first cleanup already simplifies things a lot.

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":
44
44
        unsigned long agg_offset
45
45
    struct delta_index:
46
46
        pass
47
 
    delta_index * create_delta_index(source_info *src, delta_index *old)
 
47
    delta_index * create_delta_index(source_info *src, delta_index *old) nogil
48
48
    delta_index * create_delta_index_from_delta(source_info *delta,
49
 
                                                delta_index *old)
50
 
    void free_delta_index(delta_index *index)
 
49
                                                delta_index *old) nogil
 
50
    void free_delta_index(delta_index *index) nogil
51
51
    void *create_delta(delta_index *indexes,
52
52
             void *buf, unsigned long bufsize,
53
 
             unsigned long *delta_size, unsigned long max_delta_size)
 
53
             unsigned long *delta_size, unsigned long max_delta_size) nogil
54
54
    unsigned long get_delta_hdr_size(unsigned char **datap,
55
 
                                     unsigned char *top)
 
55
                                     unsigned char *top) nogil
56
56
    Py_ssize_t DELTA_SIZE_MIN
57
 
    void *patch_delta(void *src_buf, unsigned long src_size,
58
 
                      void *delta_buf, unsigned long delta_size,
59
 
                      unsigned long *dst_size)
60
57
 
61
58
 
62
59
cdef void *safe_malloc(size_t count) except NULL:
148
145
        src.buf = c_delta
149
146
        src.size = c_delta_size
150
147
        src.agg_offset = self._source_offset + unadded_bytes
151
 
        index = create_delta_index_from_delta(src, self._index)
 
148
        with nogil:
 
149
            index = create_delta_index_from_delta(src, self._index)
152
150
        self._source_offset = src.agg_offset + src.size
153
151
        if index != NULL:
154
152
            free_delta_index(self._index)
188
186
        self._source_offset = src.agg_offset + src.size
189
187
        # We delay creating the index on the first insert
190
188
        if source_location != 0:
191
 
            index = create_delta_index(src, self._index)
 
189
            with nogil:
 
190
                index = create_delta_index(src, self._index)
192
191
            if index != NULL:
193
192
                free_delta_index(self._index)
194
193
                self._index = index
201
200
 
202
201
        # We know that self._index is already NULL, so whatever
203
202
        # create_delta_index returns is fine
204
 
        self._index = create_delta_index(&self._source_infos[0], NULL)
 
203
        with nogil:
 
204
            self._index = create_delta_index(&self._source_infos[0], NULL)
205
205
        assert self._index != NULL
206
206
 
207
207
    cdef _expand_sources(self):
218
218
        cdef Py_ssize_t target_size
219
219
        cdef void * delta
220
220
        cdef unsigned long delta_size
 
221
        cdef unsigned long c_max_delta_size
221
222
 
222
223
        if self._index == NULL:
223
224
            if len(self._sources) == 0:
234
235
        # TODO: inline some of create_delta so we at least don't have to double
235
236
        #       malloc, and can instead use PyString_FromStringAndSize, to
236
237
        #       allocate the bytes into the final string
237
 
        delta = create_delta(self._index,
238
 
                             target, target_size,
239
 
                             &delta_size, max_delta_size)
 
238
        c_max_delta_size = max_delta_size
 
239
        with nogil:
 
240
            delta = create_delta(self._index,
 
241
                                 target, target_size,
 
242
                                 &delta_size, c_max_delta_size)
240
243
        result = None
241
244
        if delta:
242
245
            result = PyString_FromStringAndSize(<char *>delta, delta_size)
276
279
 
277
280
 
278
281
cdef unsigned char *_decode_copy_instruction(unsigned char *bytes,
279
 
    unsigned char cmd, unsigned int *offset, unsigned int *length):
 
282
    unsigned char cmd, unsigned int *offset,
 
283
    unsigned int *length) nogil: # cannot_raise
280
284
    """Decode a copy instruction from the next few bytes.
281
285
 
282
286
    A copy instruction is a variable number of bytes, so we will parse the
326
330
    cdef unsigned char *dst_buf, *out, cmd
327
331
    cdef Py_ssize_t size
328
332
    cdef unsigned int cp_off, cp_size
 
333
    cdef int failed
329
334
 
330
335
    data = <unsigned char *>delta
331
336
    top = data + delta_size
335
340
    result = PyString_FromStringAndSize(NULL, size)
336
341
    dst_buf = <unsigned char*>PyString_AS_STRING(result)
337
342
 
338
 
    out = dst_buf
339
 
    while (data < top):
340
 
        cmd = data[0]
341
 
        data = data + 1
342
 
        if (cmd & 0x80):
343
 
            # Copy instruction
344
 
            data = _decode_copy_instruction(data, cmd, &cp_off, &cp_size)
345
 
            if (cp_off + cp_size < cp_size or
346
 
                cp_off + cp_size > source_size or
347
 
                cp_size > size):
348
 
                raise RuntimeError('Something wrong with:'
349
 
                    ' cp_off = %s, cp_size = %s'
350
 
                    ' source_size = %s, size = %s'
351
 
                    % (cp_off, cp_size, source_size, size))
352
 
            memcpy(out, source + cp_off, cp_size)
353
 
            out = out + cp_size
354
 
            size = size - cp_size
355
 
        else:
356
 
            # Insert instruction
357
 
            if cmd == 0:
358
 
                # cmd == 0 is reserved for future encoding
359
 
                # extensions. In the mean time we must fail when
360
 
                # encountering them (might be data corruption).
361
 
                raise RuntimeError('Got delta opcode: 0, not supported')
362
 
            if (cmd > size):
363
 
                raise RuntimeError('Insert instruction longer than remaining'
364
 
                    ' bytes: %d > %d' % (cmd, size))
365
 
            memcpy(out, data, cmd)
366
 
            out = out + cmd
367
 
            data = data + cmd
368
 
            size = size - cmd
 
343
    failed = 0
 
344
    with nogil:
 
345
        out = dst_buf
 
346
        while (data < top):
 
347
            cmd = data[0]
 
348
            data = data + 1
 
349
            if (cmd & 0x80):
 
350
                # Copy instruction
 
351
                data = _decode_copy_instruction(data, cmd, &cp_off, &cp_size)
 
352
                if (cp_off + cp_size < cp_size or
 
353
                    cp_off + cp_size > source_size or
 
354
                    cp_size > size):
 
355
                    failed = 1
 
356
                    break
 
357
                memcpy(out, source + cp_off, cp_size)
 
358
                out = out + cp_size
 
359
                size = size - cp_size
 
360
            else:
 
361
                # Insert instruction
 
362
                if cmd == 0:
 
363
                    # cmd == 0 is reserved for future encoding
 
364
                    # extensions. In the mean time we must fail when
 
365
                    # encountering them (might be data corruption).
 
366
                    failed = 2
 
367
                    break
 
368
                if cmd > size:
 
369
                    failed = 3
 
370
                    break
 
371
                memcpy(out, data, cmd)
 
372
                out = out + cmd
 
373
                data = data + cmd
 
374
                size = size - cmd
 
375
    if failed:
 
376
        if failed == 1:
 
377
            raise ValueError('Something wrong with:'
 
378
                ' cp_off = %s, cp_size = %s'
 
379
                ' source_size = %s, size = %s'
 
380
                % (cp_off, cp_size, source_size, size))
 
381
        elif failed == 2:
 
382
            raise ValueError('Got delta opcode: 0, not supported')
 
383
        elif failed == 3:
 
384
            raise ValueError('Insert instruction longer than remaining'
 
385
                ' bytes: %d > %d' % (cmd, size))
369
386
 
370
387
    # sanity check
371
388
    if (data != top or size != 0):