[sheepdog] [PATCH 2/2] sheep/http: optimize read/write object by using async request
Robin Dong
robin.k.dong at gmail.com
Tue Dec 17 09:33:24 CET 2013
Reviewed-by: Robin Dong <sanbai at taobao.com>
2013/12/16 Liu Yuan <namei.unix at gmail.com>
> Also add Robin and myself to the contributor list of this file
>
> Signed-off-by: Liu Yuan <namei.unix at gmail.com>
> ---
> sheep/http/kv.c | 102
> ++++++++++++++++++++++++++++++++++++++++---------------
> 1 file changed, 75 insertions(+), 27 deletions(-)
>
> diff --git a/sheep/http/kv.c b/sheep/http/kv.c
> index c578716..8dc4db8 100644
> --- a/sheep/http/kv.c
> +++ b/sheep/http/kv.c
> @@ -1,5 +1,7 @@
> /*
> * Copyright (C) 2013 MORITA Kazutaka <morita.kazutaka at gmail.com>
> + * Copyright (C) 2013 Robin Dong <sanbai at taobao.com>
> + * Copyright (C) 2013 Liu Yuan <namei.unix at gmail.com>
> *
> * This program is free software; you can redistribute it and/or
> * modify it under the terms of the GNU General Public License version
> @@ -919,11 +921,57 @@ out:
> return ret;
> }
>
> +static int vdi_read_write(uint32_t vid, char *data, size_t length,
> + off_t offset, bool read)
> +{
> + struct sd_req hdr;
> + uint32_t idx = offset / SD_DATA_OBJ_SIZE;
> + uint64_t done = 0;
> + struct request_iocb *iocb;
> + int ret;
> +
> + iocb = local_req_init();
> + if (!iocb)
> + return SD_RES_SYSTEM_ERROR;
> +
> + offset %= SD_DATA_OBJ_SIZE;
> + while (done < length) {
> + size_t len = min(length - done, SD_DATA_OBJ_SIZE - offset);
> +
> + if (read) {
> + sd_init_req(&hdr, SD_OP_READ_OBJ);
> + } else {
> + sd_init_req(&hdr, SD_OP_CREATE_AND_WRITE_OBJ);
> + hdr.flags = SD_FLAG_CMD_WRITE;
> + }
> + hdr.data_length = len;
> + hdr.obj.oid = vid_to_data_oid(vid, idx);
> + hdr.obj.offset = offset;
> +
> + ret = exec_local_req_async(&hdr, data, iocb);
> + if (ret != SD_RES_SUCCESS)
> + sd_err("failed to write object %" PRIx64 ", %s",
> + hdr.obj.oid, sd_strerror(ret));
> +
> + offset += len;
> + if (offset == SD_DATA_OBJ_SIZE) {
> + offset = 0;
> + idx++;
> + }
> + done += len;
> + data += len;
> + }
> +
> + return local_req_wait(iocb);
> +}
> +
> +#define READ_WRITE_BUFFER (SD_DATA_OBJ_SIZE * 25) /* no rationale */
> +
> static int kv_create_extent_onode(struct http_request *req, uint32_t
> data_vid,
> struct kv_onode *onode, ssize_t
> *total_size)
> {
> ssize_t size;
> - uint64_t start = 0, count, limit, block;
> + uint64_t start = 0, count, done = 0, total, offset;
> int ret;
> char *data_buf = NULL;
>
> @@ -931,6 +979,7 @@ static int kv_create_extent_onode(struct http_request
> *req, uint32_t data_vid,
> sys->cdrv->lock(data_vid);
> ret = oalloc_new_prepare(data_vid, &start, count);
> sys->cdrv->unlock(data_vid);
> + sd_debug("start: %lu, count: %lu", start, count);
> if (ret != SD_RES_SUCCESS) {
> sd_err("Failed to prepare allocation of %lu bytes!",
> req->data_length);
> @@ -939,24 +988,23 @@ static int kv_create_extent_onode(struct
> http_request *req, uint32_t data_vid,
> }
>
> /* receive and write data at first, then write onode */
> - data_buf = xmalloc(SD_DATA_OBJ_SIZE);
> -
> - sd_debug("start: %lu, count: %lu", start, count);
> - for (block = start, limit = start + count; block < limit; block++)
> {
> - sd_debug("block: %lu, limit: %lu", block, limit);
> - size = http_request_read(req, data_buf, SD_DATA_OBJ_SIZE);
> - *total_size += size;
> - ret = sd_write_object(vid_to_data_oid(data_vid, block),
> - data_buf, size, 0, true);
> + data_buf = xmalloc(READ_WRITE_BUFFER);
> + offset = start * SD_DATA_OBJ_SIZE;
> + total = req->data_length;
> + while (done < total) {
> + size = http_request_read(req, data_buf, READ_WRITE_BUFFER);
> + ret = vdi_read_write(data_vid, data_buf, size, offset,
> false);
> if (ret != SD_RES_SUCCESS) {
> sd_err("Failed to write data object for %" PRIx32"
> %s",
> data_vid, sd_strerror(ret));
> goto out;
> }
> - if (size < SD_DATA_OBJ_SIZE)
> - break;
> + done += size;
> + offset += size;
> }
>
> + *total_size = done;
> +
> sd_debug("DATA_LENGTH: %lu, total size: %lu, last blocks: %lu",
> req->data_length, *total_size, start);
>
> @@ -975,6 +1023,7 @@ static int kv_create_extent_onode(struct http_request
> *req, uint32_t data_vid,
> onode->o_extent[0].count = count;
> onode->hdr.nr_extent = 1;
> out:
> + free(data_buf);
> return ret;
> }
>
> @@ -1075,32 +1124,31 @@ static int kv_read_extent_onode(struct
> http_request *req,
> struct kv_onode *onode)
> {
> struct onode_extent *ext;
> - uint64_t oid, block, size, total_size, limit;
> + uint64_t size, total, total_size, offset, done = 0;
> uint32_t i;
> int ret;
> char *data_buf = NULL;
>
> - data_buf = xmalloc(SD_DATA_OBJ_SIZE);
> -
> + data_buf = xmalloc(READ_WRITE_BUFFER);
> total_size = onode->hdr.size;
> - ext = onode->o_extent;
> for (i = 0; i < onode->hdr.nr_extent; i++) {
> - limit = ext->count + ext->start;
> - for (block = ext->start; block < limit; block++) {
> - oid = vid_to_data_oid(onode->hdr.data_vid, block);
> - if (total_size < SD_DATA_OBJ_SIZE)
> - size = total_size;
> - else
> - size = SD_DATA_OBJ_SIZE;
> - ret = sd_read_object(oid, data_buf, size, 0);
> + ext = onode->o_extent + i;
> + total = min(ext->count * SD_DATA_OBJ_SIZE, total_size);
> + offset = ext->start * SD_DATA_OBJ_SIZE;
> + while (done < total) {
> + size = MIN(total - done, READ_WRITE_BUFFER);
> + sd_err("%ld", size);
> + ret = vdi_read_write(onode->hdr.data_vid, data_buf,
> + size, offset, true);
> if (ret != SD_RES_SUCCESS) {
> - sd_err("Failed to read oid %lx", oid);
> + sd_err("Failed to read for vid %"PRIx32,
> + onode->hdr.data_vid);
> goto out;
> }
> http_request_write(req, data_buf, size);
> + done += size;
> + offset += size;
> total_size -= size;
> - sd_debug("read extented block %lu, size %lu",
> - block, size);
> }
> }
> out:
> --
> 1.7.9.5
>
> --
> sheepdog mailing list
> sheepdog at lists.wpkg.org
> http://lists.wpkg.org/mailman/listinfo/sheepdog
>
--
--
Best Regard
Robin Dong
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.wpkg.org/pipermail/sheepdog/attachments/20131217/b3d46ea4/attachment-0004.html>
More information about the sheepdog
mailing list