~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_chk_map_pyx.pyx

(jameinel) Allow 'bzr serve' to interpret SIGHUP as a graceful shutdown.
 (bug #795025) (John A Meinel)

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)
39
 
    unsigned long PyInt_AsUnsignedLongMask(object) except? -1
 
40
    void PyString_InternInPlace(PyObject **)
 
41
    long PyInt_AS_LONG(object)
40
42
 
41
43
    int PyDict_SetItem(object d, object k, object v) except -1
42
44
 
43
 
    object PyTuple_New(Py_ssize_t count)
44
 
    void PyTuple_SET_ITEM(object t, Py_ssize_t offset, object)
45
 
 
46
45
    void Py_INCREF(object)
 
46
    void Py_DECREF_ptr "Py_DECREF" (PyObject *)
47
47
 
48
 
    PyObject * PyTuple_GET_ITEM_ptr "PyTuple_GET_ITEM" (object t,
49
 
                                                        Py_ssize_t offset)
50
 
    int PyString_CheckExact_ptr "PyString_CheckExact" (PyObject *p)
51
 
    Py_ssize_t PyString_GET_SIZE_ptr "PyString_GET_SIZE" (PyObject *s)
52
 
    char *PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *s)
53
48
    object PyString_FromStringAndSize(char*, Py_ssize_t)
54
49
 
55
50
# cimport all of the definitions we will need to access
56
51
from _static_tuple_c cimport StaticTuple,\
57
52
    import_static_tuple_c, StaticTuple_New, \
58
 
    StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact
59
 
 
60
 
cdef extern from "_static_tuple_c.h":
61
 
    # Defined explicitly rather than cimport-ing. Trying to use cimport, the
62
 
    # type for PyObject is a different class that happens to have the same
63
 
    # name...
64
 
    PyObject * StaticTuple_GET_ITEM_ptr "StaticTuple_GET_ITEM" (StaticTuple,
65
 
                                                                Py_ssize_t)
 
53
    StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact, \
 
54
    StaticTuple_GET_SIZE
66
55
 
67
56
cdef object crc32
68
57
from zlib import crc32
93
82
    return NULL
94
83
 
95
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
 
96
100
def _search_key_16(key):
97
101
    """See chk_map._search_key_16."""
98
102
    cdef Py_ssize_t num_bits
111
115
        if i > 0:
112
116
            c_out[0] = c'\x00'
113
117
            c_out = c_out + 1
114
 
        crc_val = PyInt_AsUnsignedLongMask(crc32(key[i]))
 
118
        crc_val = PyInt_AS_LONG(crc32(key[i]))
115
119
        # Hex(val) order
116
120
        sprintf(c_out, '%08X', crc_val)
117
121
        c_out = c_out + 8
136
140
        if i > 0:
137
141
            c_out[0] = c'\x00'
138
142
            c_out = c_out + 1
139
 
        crc_val = PyInt_AsUnsignedLongMask(crc32(key[i]))
 
143
        crc_val = PyInt_AS_LONG(crc32(key[i]))
140
144
        # MSB order
141
145
        c_out[0] = (crc_val >> 24) & 0xFF
142
146
        c_out[1] = (crc_val >> 16) & 0xFF
171
175
    return value
172
176
 
173
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
 
174
188
def _deserialise_leaf_node(bytes, key, search_key_func=None):
175
189
    """Deserialise bytes, with key key, into a LeafNode.
176
190
 
188
202
    cdef StaticTuple entry_bits
189
203
 
190
204
    if _LeafNode is None:
191
 
        from bzrlib import chk_map
192
 
        _LeafNode = chk_map.LeafNode
193
 
        _InternalNode = chk_map.InternalNode
194
 
        _unknown = chk_map._unknown
 
205
        _import_globals()
195
206
 
196
207
    result = _LeafNode(search_key_func=search_key_func)
197
208
    # Splitlines can split on '\r' so don't use it, split('\n') adds an
295
306
                                               next_null - entry_start)
296
307
            Py_INCREF(entry)
297
308
            StaticTuple_SET_ITEM(entry_bits, i, entry)
298
 
        if len(entry_bits) != width:
 
309
        if StaticTuple_GET_SIZE(entry_bits) != width:
299
310
            raise AssertionError(
300
311
                'Incorrect number of elements (%d vs %d)'
301
312
                % (len(entry_bits)+1, width + 1))
331
342
    cdef char *prefix, *line_prefix, *next_null, *c_item_prefix
332
343
 
333
344
    if _InternalNode is None:
334
 
        from bzrlib import chk_map
335
 
        _LeafNode = chk_map.LeafNode
336
 
        _InternalNode = chk_map.InternalNode
337
 
        _unknown = chk_map._unknown
 
345
        _import_globals()
338
346
    result = _InternalNode(search_key_func=search_key_func)
339
347
 
340
348
    if not StaticTuple_CheckExact(key):
395
403
    result._node_width = len(item_prefix)
396
404
    result._search_prefix = PyString_FromStringAndSize(prefix, prefix_length)
397
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, got %r' % (type(bytes),))
 
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(
 
425
            'Kind section should end with ": ", got %r' % str(cur_end[:2],))
 
426
    file_id_str = cur_end + 2
 
427
    # file_id is now the data up until the next newline
 
428
    cur_end = <char*>memchr(file_id_str, c'\n', byte_end - file_id_str)
 
429
    if cur_end == NULL:
 
430
        raise ValueError('no newline after file-id')
 
431
    file_id = safe_interned_string_from_size(file_id_str,
 
432
                                             cur_end - file_id_str)
 
433
    # this is the end of the parent_str
 
434
    cur_end = <char*>memchr(cur_end + 1, c'\n', byte_end - cur_end - 1)
 
435
    if cur_end == NULL:
 
436
        raise ValueError('no newline after parent_str')
 
437
    # end of the name str
 
438
    cur_end = <char*>memchr(cur_end + 1, c'\n', byte_end - cur_end - 1)
 
439
    if cur_end == NULL:
 
440
        raise ValueError('no newline after name str')
 
441
    # the next section is the revision info
 
442
    revision_str = cur_end + 1
 
443
    cur_end = <char*>memchr(cur_end + 1, c'\n', byte_end - cur_end - 1)
 
444
    if cur_end == NULL:
 
445
        # This is probably a dir: entry, which has revision as the last item
 
446
        cur_end = byte_end
 
447
    revision = safe_interned_string_from_size(revision_str,
 
448
        cur_end - revision_str)
 
449
    key = StaticTuple_New(2)
 
450
    Py_INCREF(file_id)
 
451
    StaticTuple_SET_ITEM(key, 0, file_id) 
 
452
    Py_INCREF(revision)
 
453
    StaticTuple_SET_ITEM(key, 1, revision) 
 
454
    return StaticTuple_Intern(key)