~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_chk_map_pyx.pyx

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-05-11 17:22:12 UTC
  • mfrom: (5218.2.3 bytes_to_entry_c)
  • Revision ID: pqm@pqm.ubuntu.com-20100511172212-1khjwgh7p1d9zxlu
(jam) Some chk_map and CHKInventory tweaks to reduce CPU overhead for
        full fetch.

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 **)
39
41
    unsigned long PyInt_AsUnsignedLongMask(object) except? -1
40
42
 
41
43
    int PyDict_SetItem(object d, object k, object v) except -1
44
46
    void PyTuple_SET_ITEM(object t, Py_ssize_t offset, object)
45
47
 
46
48
    void Py_INCREF(object)
 
49
    void Py_DECREF_ptr "Py_DECREF" (PyObject *)
47
50
 
48
51
    PyObject * PyTuple_GET_ITEM_ptr "PyTuple_GET_ITEM" (object t,
49
52
                                                        Py_ssize_t offset)
55
58
# cimport all of the definitions we will need to access
56
59
from _static_tuple_c cimport StaticTuple,\
57
60
    import_static_tuple_c, StaticTuple_New, \
58
 
    StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact
 
61
    StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact, \
 
62
    StaticTuple_GET_SIZE
59
63
 
60
64
cdef extern from "_static_tuple_c.h":
61
65
    # Defined explicitly rather than cimport-ing. Trying to use cimport, the
93
97
    return NULL
94
98
 
95
99
 
 
100
cdef object safe_interned_string_from_size(char *s, Py_ssize_t size):
 
101
    cdef PyObject *py_str
 
102
    if size < 0:
 
103
        raise AssertionError(
 
104
            'tried to create a string with an invalid size: %d @0x%x'
 
105
            % (size, <int>s))
 
106
    py_str = PyString_FromStringAndSize_ptr(s, size)
 
107
    PyString_InternInPlace(&py_str)
 
108
    result = <object>py_str
 
109
    # Casting a PyObject* to an <object> triggers an INCREF from Pyrex, so we
 
110
    # DECREF it to avoid geting immortal strings
 
111
    Py_DECREF_ptr(py_str)
 
112
    return result
 
113
 
 
114
 
96
115
def _search_key_16(key):
97
116
    """See chk_map._search_key_16."""
98
117
    cdef Py_ssize_t num_bits
171
190
    return value
172
191
 
173
192
 
 
193
cdef _import_globals():
 
194
    """Set the global attributes. Done lazy to avoid recursive import loops."""
 
195
    global _LeafNode, _InternalNode, _unknown
 
196
 
 
197
    from bzrlib import chk_map
 
198
    _LeafNode = chk_map.LeafNode
 
199
    _InternalNode = chk_map.InternalNode
 
200
    _unknown = chk_map._unknown
 
201
 
 
202
 
174
203
def _deserialise_leaf_node(bytes, key, search_key_func=None):
175
204
    """Deserialise bytes, with key key, into a LeafNode.
176
205
 
188
217
    cdef StaticTuple entry_bits
189
218
 
190
219
    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
 
220
        _import_globals()
195
221
 
196
222
    result = _LeafNode(search_key_func=search_key_func)
197
223
    # Splitlines can split on '\r' so don't use it, split('\n') adds an
295
321
                                               next_null - entry_start)
296
322
            Py_INCREF(entry)
297
323
            StaticTuple_SET_ITEM(entry_bits, i, entry)
298
 
        if len(entry_bits) != width:
 
324
        if StaticTuple_GET_SIZE(entry_bits) != width:
299
325
            raise AssertionError(
300
326
                'Incorrect number of elements (%d vs %d)'
301
327
                % (len(entry_bits)+1, width + 1))
331
357
    cdef char *prefix, *line_prefix, *next_null, *c_item_prefix
332
358
 
333
359
    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
 
360
        _import_globals()
338
361
    result = _InternalNode(search_key_func=search_key_func)
339
362
 
340
363
    if not StaticTuple_CheckExact(key):
395
418
    result._node_width = len(item_prefix)
396
419
    result._search_prefix = PyString_FromStringAndSize(prefix, prefix_length)
397
420
    return result
 
421
 
 
422
 
 
423
def _bytes_to_text_key(bytes):
 
424
    """Take a CHKInventory value string and return a (file_id, rev_id) tuple"""
 
425
    cdef StaticTuple key
 
426
    cdef char *byte_str, *cur_end, *file_id_str, *byte_end
 
427
    cdef char *revision_str
 
428
    cdef Py_ssize_t byte_size, pos, file_id_len
 
429
 
 
430
    if not PyString_CheckExact(bytes):
 
431
        raise TypeError('bytes must be a string')
 
432
    byte_str = PyString_AS_STRING(bytes)
 
433
    byte_size = PyString_GET_SIZE(bytes)
 
434
    byte_end = byte_str + byte_size
 
435
    cur_end = <char*>memchr(byte_str, c':', byte_size)
 
436
    if cur_end == NULL:
 
437
        raise ValueError('No kind section found.')
 
438
    if cur_end[1] != c' ':
 
439
        raise ValueError('Kind section should end with ": "')
 
440
    file_id_str = cur_end + 2
 
441
    # file_id is now the data up until the next newline
 
442
    cur_end = <char*>memchr(file_id_str, c'\n', byte_end - file_id_str)
 
443
    if cur_end == NULL:
 
444
        raise ValueError('no newline after file-id')
 
445
    file_id = safe_interned_string_from_size(file_id_str,
 
446
                                             cur_end - file_id_str)
 
447
    # this is the end of the parent_str
 
448
    cur_end = <char*>memchr(cur_end + 1, c'\n', byte_end - cur_end - 1)
 
449
    if cur_end == NULL:
 
450
        raise ValueError('no newline after parent_str')
 
451
    # end of the name str
 
452
    cur_end = <char*>memchr(cur_end + 1, c'\n', byte_end - cur_end - 1)
 
453
    if cur_end == NULL:
 
454
        raise ValueError('no newline after name str')
 
455
    # the next section is the revision info
 
456
    revision_str = cur_end + 1
 
457
    cur_end = <char*>memchr(cur_end + 1, c'\n', byte_end - cur_end - 1)
 
458
    if cur_end == NULL:
 
459
        # This is probably a dir: entry, which has revision as the last item
 
460
        cur_end = byte_end
 
461
    revision = safe_interned_string_from_size(revision_str,
 
462
        cur_end - revision_str)
 
463
    key = StaticTuple_New(2)
 
464
    Py_INCREF(file_id)
 
465
    StaticTuple_SET_ITEM(key, 0, file_id) 
 
466
    Py_INCREF(revision)
 
467
    StaticTuple_SET_ITEM(key, 1, revision) 
 
468
    return StaticTuple_Intern(key)