/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/_chk_map_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) 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
29
29
 
30
30
cdef extern from "Python.h":
31
31
    ctypedef int Py_ssize_t # Required for older pyrex versions
32
 
    ctypedef struct PyObject:
 
32
    struct _PyObject:
33
33
        pass
 
34
    ctypedef _PyObject PyObject
34
35
    int PyTuple_CheckExact(object p)
35
36
    Py_ssize_t PyTuple_GET_SIZE(object t)
36
37
    int PyString_CheckExact(object)
51
52
    char *PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *s)
52
53
    object PyString_FromStringAndSize(char*, Py_ssize_t)
53
54
 
54
 
# cimport all of the definitions we will need to access
55
 
from _static_tuple_c cimport StaticTuple,\
56
 
    import_static_tuple_c, StaticTuple_New, \
57
 
    StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact
58
 
 
59
 
cdef extern from "_static_tuple_c.h":
60
 
    # Defined explicitly rather than cimport-ing. Trying to use cimport, the
61
 
    # type for PyObject is a different class that happens to have the same
62
 
    # name...
63
 
    PyObject * StaticTuple_GET_ITEM_ptr "StaticTuple_GET_ITEM" (StaticTuple,
64
 
                                                                Py_ssize_t)
65
 
 
66
55
cdef extern from "zlib.h":
67
56
    ctypedef unsigned long uLong
68
57
    ctypedef unsigned int uInt
71
60
    uLong crc32(uLong crc, Bytef *buf, uInt len)
72
61
 
73
62
 
74
 
# Set up the StaticTuple C_API functionality
75
 
import_static_tuple_c()
76
 
 
77
 
cdef object _LeafNode
78
63
_LeafNode = None
79
 
cdef object _InternalNode
80
64
_InternalNode = None
81
 
cdef object _unknown
82
65
_unknown = None
83
66
 
84
 
# We shouldn't just copy this from _dirstate_helpers_pyx
85
 
cdef void* _my_memrchr(void *s, int c, size_t n): # cannot_raise
 
67
# We shouldn't just copy this from _dirstate_helpers_c
 
68
cdef void* _my_memrchr(void *s, int c, size_t n):
86
69
    # memrchr seems to be a GNU extension, so we have to implement it ourselves
87
70
    cdef char *pos
88
71
    cdef char *start
108
91
    cdef char *c_out
109
92
    cdef PyObject *bit
110
93
 
111
 
    if not StaticTuple_CheckExact(key):
112
 
        raise TypeError('key %r is not a StaticTuple' % (key,))
113
 
    num_bits = len(key)
 
94
    if not PyTuple_CheckExact(key):
 
95
        raise TypeError('key %r is not a tuple' % (key,))
 
96
    num_bits = PyTuple_GET_SIZE(key)
114
97
    # 4 bytes per crc32, and another 1 byte between bits
115
98
    num_out_bytes = (9 * num_bits) - 1
116
99
    out = PyString_FromStringAndSize(NULL, num_out_bytes)
122
105
        # We use the _ptr variant, because GET_ITEM returns a borrowed
123
106
        # reference, and Pyrex assumes that returned 'object' are a new
124
107
        # reference
125
 
        bit = StaticTuple_GET_ITEM_ptr(key, i)
 
108
        bit = PyTuple_GET_ITEM_ptr(key, i)
126
109
        if not PyString_CheckExact_ptr(bit):
127
110
            raise TypeError('Bit %d of %r is not a string' % (i, key))
128
111
        c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
146
129
    cdef char *c_out
147
130
    cdef PyObject *bit
148
131
 
149
 
    if not StaticTuple_CheckExact(key):
150
 
        raise TypeError('key %r is not a StaticTuple' % (key,))
151
 
    num_bits = len(key)
 
132
    if not PyTuple_CheckExact(key):
 
133
        raise TypeError('key %r is not a tuple' % (key,))
 
134
    num_bits = PyTuple_GET_SIZE(key)
152
135
    # 4 bytes per crc32, and another 1 byte between bits
153
136
    num_out_bytes = (5 * num_bits) - 1
154
137
    out = PyString_FromStringAndSize(NULL, num_out_bytes)
157
140
        if i > 0:
158
141
            c_out[0] = c'\x00'
159
142
            c_out = c_out + 1
160
 
        bit = StaticTuple_GET_ITEM_ptr(key, i)
 
143
        bit = PyTuple_GET_ITEM_ptr(key, i)
161
144
        if not PyString_CheckExact_ptr(bit):
162
 
            raise TypeError('Bit %d of %r is not a string: %r'
163
 
                            % (i, key, <object>bit))
 
145
            raise TypeError('Bit %d of %r is not a string: %r' % (i, key,
 
146
            <object>bit))
164
147
        c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
165
148
        c_len = PyString_GET_SIZE_ptr(bit)
166
149
        crc_val = crc32(0, c_bit, c_len)
212
195
    cdef char *prefix, *value_start, *prefix_tail
213
196
    cdef char *next_null, *last_null, *line_start
214
197
    cdef char *c_entry, *entry_start
215
 
    cdef StaticTuple entry_bits
216
198
 
217
199
    if _LeafNode is None:
218
200
        from bzrlib import chk_map
283
265
            if next_line == NULL:
284
266
                raise ValueError('missing trailing newline')
285
267
            cur = next_line + 1
286
 
        entry_bits = StaticTuple_New(width)
 
268
        entry_bits = PyTuple_New(width)
287
269
        for i from 0 <= i < num_prefix_bits:
288
 
            # TODO: Use PyList_GetItem, or turn prefix_bits into a
289
 
            #       tuple/StaticTuple
290
270
            entry = prefix_bits[i]
291
271
            # SET_ITEM 'steals' a reference
292
272
            Py_INCREF(entry)
293
 
            StaticTuple_SET_ITEM(entry_bits, i, entry)
 
273
            PyTuple_SET_ITEM(entry_bits, i, entry)
294
274
        value = PyString_FromStringAndSize(value_start, next_line - value_start)
295
275
        # The next entry bit needs the 'tail' from the prefix, and first part
296
276
        # of the line
308
288
            memcpy(c_entry + prefix_tail_len, line_start, next_null - line_start)
309
289
        Py_INCREF(entry)
310
290
        i = num_prefix_bits
311
 
        StaticTuple_SET_ITEM(entry_bits, i, entry)
 
291
        PyTuple_SET_ITEM(entry_bits, i, entry)
312
292
        while next_null != last_null: # We have remaining bits
313
293
            i = i + 1
314
294
            if i > width:
321
301
            entry = PyString_FromStringAndSize(entry_start,
322
302
                                               next_null - entry_start)
323
303
            Py_INCREF(entry)
324
 
            StaticTuple_SET_ITEM(entry_bits, i, entry)
 
304
            PyTuple_SET_ITEM(entry_bits, i, entry)
325
305
        if len(entry_bits) != width:
326
306
            raise AssertionError(
327
307
                'Incorrect number of elements (%d vs %d)'
328
308
                % (len(entry_bits)+1, width + 1))
329
 
        entry_bits = StaticTuple_Intern(entry_bits)
330
309
        PyDict_SetItem(items, entry_bits, value)
331
310
    if len(items) != length:
332
311
        raise ValueError("item count (%d) mismatch for key %s,"
364
343
        _unknown = chk_map._unknown
365
344
    result = _InternalNode(search_key_func=search_key_func)
366
345
 
367
 
    if not StaticTuple_CheckExact(key):
368
 
        raise TypeError('key %r is not a StaticTuple' % (key,))
369
346
    if not PyString_CheckExact(bytes):
370
347
        raise TypeError('bytes must be a plain string not %s' % (type(bytes),))
371
348
 
407
384
        memcpy(c_item_prefix + prefix_length, cur, next_null - cur)
408
385
        flat_key = PyString_FromStringAndSize(next_null + 1,
409
386
                                              next_line - next_null - 1)
410
 
        flat_key = StaticTuple(flat_key).intern()
411
 
        PyDict_SetItem(items, item_prefix, flat_key)
 
387
        PyDict_SetItem(items, item_prefix, (flat_key,))
412
388
        cur = next_line + 1
413
389
    assert len(items) > 0
414
390
    result._items = items
422
398
    result._node_width = len(item_prefix)
423
399
    result._search_prefix = PyString_FromStringAndSize(prefix, prefix_length)
424
400
    return result
 
401