Ticket #810: net_buffer.diff

File net_buffer.diff, 2.7 KB (added by sil2100, 11 years ago)

Try on a little more efficient split_buffer()

  • net_buffer.cpp

     
    146146
    147147
    148148static status_t append_data(net_buffer *buffer, const void *data, size_t size);
     149static status_t append_data_from_buffer(net_buffer *from, net_buffer *to,
     150                    size_t size);
    149151static status_t trim_data(net_buffer *_buffer, size_t newSize);
    150152static status_t remove_header(net_buffer *_buffer, size_t bytes);
    151153static status_t remove_trailer(net_buffer *_buffer, size_t bytes);
     
    12131215/*!
    12141216    Split the buffer at offset, the header data
    12151217    is returned as new buffer.
    1216     TODO: optimize and avoid making a copy.
    12171218*/
    12181219static net_buffer *
    12191220split_buffer(net_buffer *from, uint32 offset)
    12201221{
    1221     // TODO: Copying the whole buffer becomes less and less efficient with
    1222     // greater size - offset differences. What we actually want is a method
    1223     // to copy data from one buffer to another. Then the following should be:
    1224     // create buffer, resize, copy data. An additional append_data_from_buffer()
    1225     // method would be even better.
    1226     net_buffer *buffer = duplicate_buffer(from);
     1222    net_buffer *buffer = create_buffer(DATA_NODE_SIZE);
    12271223    if (buffer == NULL)
    12281224        return NULL;
     1225    copy_metadata(buffer, from);
    12291226
    12301227    ParanoiaChecker _(from);
    12311228    ParanoiaChecker _2(buffer);
     
    12331230    TRACE(("%ld: split_buffer(buffer %p -> %p, offset %ld)\n",
    12341231        find_thread(NULL), from, buffer, offset));
    12351232
    1236     if (trim_data(buffer, offset) == B_OK) {
     1233    if (append_data_from_buffer(from, buffer, offset) == B_OK) {
    12371234        if (remove_header(from, offset) == B_OK) {
    12381235            CHECK_BUFFER(from);
    12391236            CHECK_BUFFER(buffer);
     
    16491646}
    16501647
    16511648
     1649static status_t
     1650append_data_from_buffer(net_buffer *from, net_buffer *to, size_t size)
     1651{
     1652    net_buffer_private *source = (net_buffer_private *)from;
     1653    net_buffer_private *dest = (net_buffer_private *)to;
     1654
     1655    if (size > from->size)
     1656        return B_BAD_VALUE;
     1657    if (size == 0)
     1658        return B_OK;
     1659
     1660    data_node *nodeTo = get_node_at_offset(source, size);
     1661    if (nodeTo == NULL) {
     1662        return B_BAD_VALUE;
     1663    }
     1664
     1665    data_node *node = (data_node *)list_get_first_item(&source->buffers);
     1666    if (node == NULL) {
     1667        CHECK_BUFFER(source);
     1668        return B_ERROR;
     1669    }
     1670
     1671    while (node != nodeTo) {
     1672        if (append_data(dest, node->start, node->used) < B_OK) {
     1673            CHECK_BUFFER(dest);
     1674            return B_ERROR;
     1675        }
     1676
     1677        node = (data_node *)list_get_next_item(&source->buffers, node);
     1678    }
     1679
     1680    int32 diff = node->offset + node->used - size;
     1681    if (append_data(dest, node->start, node->used - diff) < B_OK) {
     1682        CHECK_BUFFER(dest);
     1683        return B_ERROR;
     1684    }
     1685
     1686    CHECK_BUFFER(dest);
     1687
     1688    return B_OK;
     1689}
     1690
     1691
    16521692/*!
    16531693    Removes bytes from the beginning of the buffer.
    16541694*/