~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_parse_btree_c.pyx

  • Committer: John Arbash Meinel
  • Date: 2008-08-21 21:26:17 UTC
  • mto: This revision was merged to the branch mainline in revision 3644.
  • Revision ID: john@arbash-meinel.com-20080821212617-gng6c2akl8985wcm
We have a single malloc for the final output.
We just need to collapse the intermediates.

Show diffs side-by-side

added added

removed removed

Lines of Context:
259
259
    cdef Py_ssize_t key_len
260
260
    cdef char * value
261
261
    cdef Py_ssize_t value_len
262
 
    cdef char * s
 
262
    cdef char * out
 
263
    cdef Py_ssize_t ref_len
 
264
    cdef Py_ssize_t next_len
263
265
 
264
266
    # I don't expect that we can do faster than string.join()
265
267
    string_key = '\x00'.join(node[1])
276
278
    # ref_list := ref (CR ref)*
277
279
    # ref := BYTES (NULL BYTES)*
278
280
    # value := BYTES
279
 
    if not reference_lists:
280
 
        # Simple case, we only have the key and the value
281
 
        # So we have the (key NULL NULL value LF)
282
 
        key_len = PyString_Size(string_key)
283
 
        value = PyString_AsString(node[2])
284
 
        value_len = PyString_Size(node[2])
285
 
        flat_len = (key_len + 1 + 1 + value_len + 1)
286
 
        line = PyString_FromStringAndSize(NULL, flat_len)
287
 
        # Get a pointer to the new buffer
288
 
        s = PyString_AsString(line)
289
 
        memcpy(s, PyString_AsString(string_key), key_len)
290
 
        s[key_len] = c'\0'
291
 
        s[key_len + 1] = c'\0'
292
 
        memcpy(s + key_len + 2, value, value_len)
293
 
        s[key_len + 2 + value_len] = c'\n'
294
 
    else:
 
281
    ref_len = 0
 
282
    if reference_lists:
 
283
        # Figure out how many bytes it will take to store the references
 
284
        next_len = len(node[3]) # TODO: use a Py function
 
285
        if next_len > 0:
 
286
            # If there are no nodes, we don't need to do any work
 
287
            # Otherwise we will need (len - 1) '\t' characters to separate
 
288
            # the reference lists
 
289
            ref_len = ref_len + (next_len - 1)
 
290
            for ref_list in node[3]:
 
291
                next_len = len(ref_list)
 
292
                if next_len > 0:
 
293
                    # We will need (len - 1) '\r' characters to separate the
 
294
                    # references
 
295
                    ref_len = ref_len + (next_len - 1)
 
296
                    for reference in ref_list:
 
297
                        next_len = len(reference)
 
298
                        if next_len > 0:
 
299
                            # We will need (len - 1) '\x00' characters to
 
300
                            # separate the reference key
 
301
                            ref_len = ref_len + (next_len - 1)
 
302
                            for ref in reference:
 
303
                                ref_len = ref_len + len(ref)
295
304
        flattened_references = []
296
305
        for ref_list in node[3]:
297
306
            ref_keys = []
298
307
            for reference in ref_list:
299
308
                ref_keys.append('\x00'.join(reference))
300
309
            flattened_references.append('\r'.join(ref_keys))
301
 
        line = ("%s\x00%s\x00%s\n" % (string_key,
302
 
            '\t'.join(flattened_references), node[2]))
 
310
        refs = '\t'.join(flattened_references)
 
311
 
 
312
    # So we have the (key NULL refs NULL value LF)
 
313
    key_len = PyString_Size(string_key)
 
314
    value = PyString_AsString(node[2])
 
315
    value_len = PyString_Size(node[2])
 
316
    flat_len = (key_len + 1 + ref_len + 1 + value_len + 1)
 
317
    line = PyString_FromStringAndSize(NULL, flat_len)
 
318
    # Get a pointer to the new buffer
 
319
    out = PyString_AsString(line)
 
320
    memcpy(out, PyString_AsString(string_key), key_len)
 
321
    out = out + key_len
 
322
    out[0] = c'\0'
 
323
    out = out + 1
 
324
    if ref_len > 0:
 
325
        memcpy(out, PyString_AsString(refs), ref_len)
 
326
        out = out + ref_len
 
327
    out[0] = c'\0'
 
328
    out = out + 1
 
329
    memcpy(out, value, value_len)
 
330
    out = out + value_len
 
331
    out[0] = c'\n'
303
332
    return string_key, line