/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/_groupcompress_pyx.pyx

  • Committer: John Arbash Meinel
  • Date: 2009-06-12 18:05:15 UTC
  • mto: (4371.4.5 vila-better-heads)
  • mto: This revision was merged to the branch mainline in revision 4449.
  • Revision ID: john@arbash-meinel.com-20090612180515-t0cwbjsnve094oik
Add a failing test for handling nodes that are in the same linear chain.

It fails because the ancestry skipping causes us to miss the fact that the two nodes
are actually directly related. We could check at the beginning, as the 
code used to do, but I think that will be incomplete for the more-than-two
heads cases.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2009 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
31
31
 
32
32
cdef extern from *:
33
33
    ctypedef unsigned long 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
 
34
    void * malloc(size_t)
 
35
    void * realloc(void *, size_t)
 
36
    void free(void *)
 
37
    void memcpy(void *, void *, size_t)
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) nogil
 
47
    delta_index * create_delta_index(source_info *src, delta_index *old)
48
48
    delta_index * create_delta_index_from_delta(source_info *delta,
49
 
                                                delta_index *old) nogil
50
 
    void free_delta_index(delta_index *index) nogil
 
49
                                                delta_index *old)
 
50
    void free_delta_index(delta_index *index)
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) nogil
 
53
             unsigned long *delta_size, unsigned long max_delta_size)
54
54
    unsigned long get_delta_hdr_size(unsigned char **datap,
55
 
                                     unsigned char *top) nogil
 
55
                                     unsigned char *top)
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)
57
60
 
58
61
 
59
62
cdef void *safe_malloc(size_t count) except NULL:
145
148
        src.buf = c_delta
146
149
        src.size = c_delta_size
147
150
        src.agg_offset = self._source_offset + unadded_bytes
148
 
        with nogil:
149
 
            index = create_delta_index_from_delta(src, self._index)
 
151
        index = create_delta_index_from_delta(src, self._index)
150
152
        self._source_offset = src.agg_offset + src.size
151
153
        if index != NULL:
152
154
            free_delta_index(self._index)
186
188
        self._source_offset = src.agg_offset + src.size
187
189
        # We delay creating the index on the first insert
188
190
        if source_location != 0:
189
 
            with nogil:
190
 
                index = create_delta_index(src, self._index)
 
191
            index = create_delta_index(src, self._index)
191
192
            if index != NULL:
192
193
                free_delta_index(self._index)
193
194
                self._index = index
200
201
 
201
202
        # We know that self._index is already NULL, so whatever
202
203
        # create_delta_index returns is fine
203
 
        with nogil:
204
 
            self._index = create_delta_index(&self._source_infos[0], NULL)
 
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
222
221
 
223
222
        if self._index == NULL:
224
223
            if len(self._sources) == 0:
235
234
        # TODO: inline some of create_delta so we at least don't have to double
236
235
        #       malloc, and can instead use PyString_FromStringAndSize, to
237
236
        #       allocate the bytes into the final string
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)
 
237
        delta = create_delta(self._index,
 
238
                             target, target_size,
 
239
                             &delta_size, max_delta_size)
243
240
        result = None
244
241
        if delta:
245
242
            result = PyString_FromStringAndSize(<char *>delta, delta_size)
279
276
 
280
277
 
281
278
cdef unsigned char *_decode_copy_instruction(unsigned char *bytes,
282
 
    unsigned char cmd, unsigned int *offset,
283
 
    unsigned int *length) nogil: # cannot_raise
 
279
    unsigned char cmd, unsigned int *offset, unsigned int *length):
284
280
    """Decode a copy instruction from the next few bytes.
285
281
 
286
282
    A copy instruction is a variable number of bytes, so we will parse the
330
326
    cdef unsigned char *dst_buf, *out, cmd
331
327
    cdef Py_ssize_t size
332
328
    cdef unsigned int cp_off, cp_size
333
 
    cdef int failed
334
329
 
335
330
    data = <unsigned char *>delta
336
331
    top = data + delta_size
340
335
    result = PyString_FromStringAndSize(NULL, size)
341
336
    dst_buf = <unsigned char*>PyString_AS_STRING(result)
342
337
 
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))
 
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
386
369
 
387
370
    # sanity check
388
371
    if (data != top or size != 0):