ngx_int_t
ngx_http_tfs_dedup_set(ngx_http_tfs_dedup_ctx_t *ctx,
    ngx_pool_t *pool, ngx_log_t * log)
{
    u_char               *p;
    ssize_t               data_len;
    ngx_int_t             rc;
    ngx_http_tair_data_t  tair_key, tair_value;

    data_len = 0;

    if (!ctx->md5_sumed) {
        rc = ngx_http_tfs_sum_md5(ctx->file_data, ctx->tair_key, &data_len,
                                  log);
        if (rc == NGX_ERROR) {
            return NGX_ERROR;
        }

        p = ctx->tair_key;
        p += NGX_HTTP_TFS_MD5_RESULT_LEN;

        *(uint32_t *) p = htonl(data_len);
        ctx->md5_sumed = 1;
    }

    tair_key.len = NGX_HTTP_TFS_DUPLICATE_KEY_SIZE;
    tair_key.data = ctx->tair_key;
    tair_key.type = NGX_HTTP_TAIR_BYTEARRAY;

    tair_value.len =
        NGX_HTTP_TFS_DUPLICATE_VALUE_BASE_SIZE + ctx->dup_file_name.len;
    tair_value.data = ngx_pcalloc(pool, tair_value.len);
    if (tair_value.data == NULL) {
        return NGX_ERROR;
    }
    ngx_memcpy(tair_value.data, &ctx->file_ref_count,
               NGX_HTTP_TFS_DUPLICATE_VALUE_BASE_SIZE);
    ngx_memcpy(tair_value.data + NGX_HTTP_TFS_DUPLICATE_VALUE_BASE_SIZE,
               ctx->dup_file_name.data, ctx->dup_file_name.len);
    tair_value.type = NGX_HTTP_TAIR_BYTEARRAY;
    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, log, 0,
                   "set duplicate info: "
                   "file name: %V, file ref count: %d, dup_version: %d",
                   &ctx->dup_file_name,
                   ctx->file_ref_count,
                   ctx->dup_version);

    rc = ngx_http_tfs_tair_put_helper(ctx->tair_instance, pool, log,
                                      &tair_key, &tair_value, 0/*expire*/,
                                      ctx->dup_version,
                                      ngx_http_tfs_dedup_set_handler, ctx);

    return rc;
}
ngx_int_t
ngx_http_tfs_remote_block_cache_insert(
    ngx_http_tfs_remote_block_cache_ctx_t *ctx,
    ngx_pool_t *pool, ngx_log_t *log,
    ngx_http_tfs_block_cache_key_t *key,
    ngx_http_tfs_block_cache_value_t *value)
{
    ngx_int_t             rc;
    ngx_pool_t           *tmp_pool;
    ngx_http_tair_data_t  tair_key, tair_value;

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
                   "insert remote block cache, "
                   "ns addr: %uL, block id: %uD",
                   key->ns_addr, key->block_id);

    tair_key.type = NGX_HTTP_TAIR_INT;
    tair_key.data = (u_char *)key;
    tair_key.len = NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE;

    tair_value.len = NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_VALUE_BASE_SIZE
                      + value->ds_count * sizeof(uint64_t);
    tair_value.data = ngx_pcalloc(pool, tair_value.len);
    if (tair_value.data == NULL) {
        return NGX_ERROR;
    }
    *(uint32_t*)tair_value.data = value->ds_count;
    ngx_memcpy(tair_value.data+ NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_VALUE_BASE_SIZE,
               value->ds_addrs, value->ds_count * sizeof(uint64_t));
    tair_value.type = NGX_HTTP_TAIR_INT;

    /* since we do not care returns,
     * we make a tmp pool and destroy it in callback
     */
    tmp_pool = ngx_create_pool(4096, log);
    if (tmp_pool == NULL) {
        return NGX_ERROR;
    }

    rc = ngx_http_tfs_tair_put_helper(
                                  ctx->tair_instance,
                                  tmp_pool, log,
                                  &tair_key, &tair_value,
                                  0/*expire*/, 0/* do not care version */,
                                  ngx_http_tfs_remote_block_cache_dummy_handler,
                                  (void *)tmp_pool);

    return rc;
}