/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: Robert Collins
  • Date: 2010-07-04 06:22:11 UTC
  • mto: This revision was merged to the branch mainline in revision 5332.
  • Revision ID: robertc@robertcollins.net-20100704062211-tk9hw6bnsn5x47fm
``bzrlib.lsprof.profile`` will no longer silently generate bad threaded
profiles when concurrent profile requests are made. Instead the profile
requests will be serialised. Reentrant requests will now deadlock.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
    Py_ssize_t PyTuple_GET_SIZE(object t)
36
36
    int PyString_CheckExact(object)
37
37
    char *PyString_AS_STRING(object s)
 
38
    PyObject *PyString_FromStringAndSize_ptr "PyString_FromStringAndSize" (char *, Py_ssize_t)
38
39
    Py_ssize_t PyString_GET_SIZE(object)
 
40
    void PyString_InternInPlace(PyObject **)
 
41
    long PyInt_AS_LONG(object)
39
42
 
40
43
    int PyDict_SetItem(object d, object k, object v) except -1
41
44
 
42
 
    object PyTuple_New(Py_ssize_t count)
43
 
    void PyTuple_SET_ITEM(object t, Py_ssize_t offset, object)
44
 
 
45
45
    void Py_INCREF(object)
 
46
    void Py_DECREF_ptr "Py_DECREF" (PyObject *)
46
47
 
47
 
    PyObject * PyTuple_GET_ITEM_ptr "PyTuple_GET_ITEM" (object t,
48
 
                                                        Py_ssize_t offset)
49
 
    int PyString_CheckExact_ptr "PyString_CheckExact" (PyObject *p)
50
 
    Py_ssize_t PyString_GET_SIZE_ptr "PyString_GET_SIZE" (PyObject *s)
51
 
    char *PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *s)
52
48
    object PyString_FromStringAndSize(char*, Py_ssize_t)
53
49
 
54
50
# cimport all of the definitions we will need to access
55
51
from _static_tuple_c cimport StaticTuple,\
56
52
    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
 
cdef extern from "zlib.h":
67
 
    ctypedef unsigned long uLong
68
 
    ctypedef unsigned int uInt
69
 
    ctypedef unsigned char Bytef
70
 
 
71
 
    uLong crc32(uLong crc, Bytef *buf, uInt len)
 
53
    StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact, \
 
54
    StaticTuple_GET_SIZE
 
55
 
 
56
cdef object crc32
 
57
from zlib import crc32
72
58
 
73
59
 
74
60
# Set up the StaticTuple C_API functionality
96
82
    return NULL
97
83
 
98
84
 
 
85
cdef object safe_interned_string_from_size(char *s, Py_ssize_t size):
 
86
    cdef PyObject *py_str
 
87
    if size < 0:
 
88
        raise AssertionError(
 
89
            'tried to create a string with an invalid size: %d @0x%x'
 
90
            % (size, <int>s))
 
91
    py_str = PyString_FromStringAndSize_ptr(s, size)
 
92
    PyString_InternInPlace(&py_str)
 
93
    result = <object>py_str
 
94
    # Casting a PyObject* to an <object> triggers an INCREF from Pyrex, so we
 
95
    # DECREF it to avoid geting immortal strings
 
96
    Py_DECREF_ptr(py_str)
 
97
    return result
 
98
 
 
99
 
99
100
def _search_key_16(key):
100
101
    """See chk_map._search_key_16."""
101
102
    cdef Py_ssize_t num_bits
102
103
    cdef Py_ssize_t i, j
103
104
    cdef Py_ssize_t num_out_bytes
104
 
    cdef Bytef *c_bit
105
 
    cdef uLong c_len
106
 
    cdef uInt crc_val
 
105
    cdef unsigned long crc_val
107
106
    cdef Py_ssize_t out_off
108
107
    cdef char *c_out
109
 
    cdef PyObject *bit
110
108
 
111
 
    if not StaticTuple_CheckExact(key):
112
 
        raise TypeError('key %r is not a StaticTuple' % (key,))
113
109
    num_bits = len(key)
114
110
    # 4 bytes per crc32, and another 1 byte between bits
115
111
    num_out_bytes = (9 * num_bits) - 1
119
115
        if i > 0:
120
116
            c_out[0] = c'\x00'
121
117
            c_out = c_out + 1
122
 
        # We use the _ptr variant, because GET_ITEM returns a borrowed
123
 
        # reference, and Pyrex assumes that returned 'object' are a new
124
 
        # reference
125
 
        bit = StaticTuple_GET_ITEM_ptr(key, i)
126
 
        if not PyString_CheckExact_ptr(bit):
127
 
            raise TypeError('Bit %d of %r is not a string' % (i, key))
128
 
        c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
129
 
        c_len = PyString_GET_SIZE_ptr(bit)
130
 
        crc_val = crc32(0, c_bit, c_len)
 
118
        crc_val = PyInt_AS_LONG(crc32(key[i]))
131
119
        # Hex(val) order
132
120
        sprintf(c_out, '%08X', crc_val)
133
121
        c_out = c_out + 8
139
127
    cdef Py_ssize_t num_bits
140
128
    cdef Py_ssize_t i, j
141
129
    cdef Py_ssize_t num_out_bytes
142
 
    cdef Bytef *c_bit
143
 
    cdef uLong c_len
144
 
    cdef uInt crc_val
 
130
    cdef unsigned long crc_val
145
131
    cdef Py_ssize_t out_off
146
132
    cdef char *c_out
147
 
    cdef PyObject *bit
148
133
 
149
 
    if not StaticTuple_CheckExact(key):
150
 
        raise TypeError('key %r is not a StaticTuple' % (key,))
151
134
    num_bits = len(key)
152
135
    # 4 bytes per crc32, and another 1 byte between bits
153
136
    num_out_bytes = (5 * num_bits) - 1
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)
161
 
        if not PyString_CheckExact_ptr(bit):
162
 
            raise TypeError('Bit %d of %r is not a string: %r'
163
 
                            % (i, key, <object>bit))
164
 
        c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
165
 
        c_len = PyString_GET_SIZE_ptr(bit)
166
 
        crc_val = crc32(0, c_bit, c_len)
 
143
        crc_val = PyInt_AS_LONG(crc32(key[i]))
167
144
        # MSB order
168
145
        c_out[0] = (crc_val >> 24) & 0xFF
169
146
        c_out[1] = (crc_val >> 16) & 0xFF
198
175
    return value
199
176
 
200
177
 
 
178
cdef _import_globals():
 
179
    """Set the global attributes. Done lazy to avoid recursive import loops."""
 
180
    global _LeafNode, _InternalNode, _unknown
 
181
 
 
182
    from bzrlib import chk_map
 
183
    _LeafNode = chk_map.LeafNode
 
184
    _InternalNode = chk_map.InternalNode
 
185
    _unknown = chk_map._unknown
 
186
 
 
187
 
201
188
def _deserialise_leaf_node(bytes, key, search_key_func=None):
202
189
    """Deserialise bytes, with key key, into a LeafNode.
203
190
 
215
202
    cdef StaticTuple entry_bits
216
203
 
217
204
    if _LeafNode is None:
218
 
        from bzrlib import chk_map
219
 
        _LeafNode = chk_map.LeafNode
220
 
        _InternalNode = chk_map.InternalNode
221
 
        _unknown = chk_map._unknown
 
205
        _import_globals()
222
206
 
223
207
    result = _LeafNode(search_key_func=search_key_func)
224
208
    # Splitlines can split on '\r' so don't use it, split('\n') adds an
322
306
                                               next_null - entry_start)
323
307
            Py_INCREF(entry)
324
308
            StaticTuple_SET_ITEM(entry_bits, i, entry)
325
 
        if len(entry_bits) != width:
 
309
        if StaticTuple_GET_SIZE(entry_bits) != width:
326
310
            raise AssertionError(
327
311
                'Incorrect number of elements (%d vs %d)'
328
312
                % (len(entry_bits)+1, width + 1))
358
342
    cdef char *prefix, *line_prefix, *next_null, *c_item_prefix
359
343
 
360
344
    if _InternalNode is None:
361
 
        from bzrlib import chk_map
362
 
        _LeafNode = chk_map.LeafNode
363
 
        _InternalNode = chk_map.InternalNode
364
 
        _unknown = chk_map._unknown
 
345
        _import_globals()
365
346
    result = _InternalNode(search_key_func=search_key_func)
366
347
 
367
348
    if not StaticTuple_CheckExact(key):
422
403
    result._node_width = len(item_prefix)
423
404
    result._search_prefix = PyString_FromStringAndSize(prefix, prefix_length)
424
405
    return result
 
406
 
 
407
 
 
408
def _bytes_to_text_key(bytes):
 
409
    """Take a CHKInventory value string and return a (file_id, rev_id) tuple"""
 
410
    cdef StaticTuple key
 
411
    cdef char *byte_str, *cur_end, *file_id_str, *byte_end
 
412
    cdef char *revision_str
 
413
    cdef Py_ssize_t byte_size, pos, file_id_len
 
414
 
 
415
    if not PyString_CheckExact(bytes):
 
416
        raise TypeError('bytes must be a string')
 
417
    byte_str = PyString_AS_STRING(bytes)
 
418
    byte_size = PyString_GET_SIZE(bytes)
 
419
    byte_end = byte_str + byte_size
 
420
    cur_end = <char*>memchr(byte_str, c':', byte_size)
 
421
    if cur_end == NULL:
 
422
        raise ValueError('No kind section found.')
 
423
    if cur_end[1] != c' ':
 
424
        raise ValueError('Kind section should end with ": "')
 
425
    file_id_str = cur_end + 2
 
426
    # file_id is now the data up until the next newline
 
427
    cur_end = <char*>memchr(file_id_str, c'\n', byte_end - file_id_str)
 
428
    if cur_end == NULL:
 
429
        raise ValueError('no newline after file-id')
 
430
    file_id = safe_interned_string_from_size(file_id_str,
 
431
                                             cur_end - file_id_str)
 
432
    # this is the end of the parent_str
 
433
    cur_end = <char*>memchr(cur_end + 1, c'\n', byte_end - cur_end - 1)
 
434
    if cur_end == NULL:
 
435
        raise ValueError('no newline after parent_str')
 
436
    # end of the name str
 
437
    cur_end = <char*>memchr(cur_end + 1, c'\n', byte_end - cur_end - 1)
 
438
    if cur_end == NULL:
 
439
        raise ValueError('no newline after name str')
 
440
    # the next section is the revision info
 
441
    revision_str = cur_end + 1
 
442
    cur_end = <char*>memchr(cur_end + 1, c'\n', byte_end - cur_end - 1)
 
443
    if cur_end == NULL:
 
444
        # This is probably a dir: entry, which has revision as the last item
 
445
        cur_end = byte_end
 
446
    revision = safe_interned_string_from_size(revision_str,
 
447
        cur_end - revision_str)
 
448
    key = StaticTuple_New(2)
 
449
    Py_INCREF(file_id)
 
450
    StaticTuple_SET_ITEM(key, 0, file_id) 
 
451
    Py_INCREF(revision)
 
452
    StaticTuple_SET_ITEM(key, 1, revision) 
 
453
    return StaticTuple_Intern(key)