X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Fstore.c;h=a8548ea88158fc81b5d5bea574d6429f25c9439c;hb=81b37a6f03b86bc0d8d3a1eee50c9c0feb51b533;hp=af25ca366eb4ddbab12d0d1b940104b234d31832;hpb=56b93c6854c139faa9de04f6907eb586acd3e6ec;p=bluesky.git diff --git a/bluesky/store.c b/bluesky/store.c index af25ca3..a8548ea 100644 --- a/bluesky/store.c +++ b/bluesky/store.c @@ -17,7 +17,7 @@ * (will) include Amazon S3 and a simple local store for testing purposes. * Operations may be performed asynchronously. */ -struct _BlueSkyStore { +struct BlueSkyStore { const BlueSkyStoreImplementation *impl; gpointer handle; @@ -105,11 +105,14 @@ BlueSkyStoreAsync *bluesky_store_async_new(BlueSkyStore *store) async->op = STORE_OP_NONE; async->key = NULL; async->data = NULL; + async->start = async->len = 0; + async->range_done = FALSE; async->result = -1; async->notifiers = NULL; async->notifier_count = 0; async->barrier = NULL; async->store_private = NULL; + async->profile = NULL; return async; } @@ -218,6 +221,29 @@ void bluesky_store_async_mark_complete(BlueSkyStoreAsync *async) g_mutex_unlock(async->store->lock); } + /* If the request was a range request but the backend read the entire + * object, select out the appropriate bytes. */ + if (async->op == STORE_OP_GET + && !async->range_done + && async->result == 0 + && async->data != NULL) { + if (async->start != 0 || async->len != 0) { + /* If the caller requesteda read outside the object, return an + * error. */ + if (async->start + async->len > async->data->len) { + g_warning("Range request outside object boundaries!\n"); + async->result = -1; + } else { + if (async->len == 0) + async->len = async->data->len - async->start; + BlueSkyRCStr *newstr = bluesky_string_new(g_memdup(&async->data->data[async->start], async->len), async->len); + bluesky_string_unref(async->data); + async->data = newstr; + async->range_done = TRUE; + } + } + } + async->status = ASYNC_COMPLETE; g_cond_broadcast(async->completion_cond); @@ -230,6 +256,18 @@ void bluesky_store_async_mark_complete(BlueSkyStoreAsync *async) g_thread_pool_push(notifier_thread_pool, nl, NULL); } + if (async->profile) { + bluesky_profile_add_event( + async->profile, + g_strdup_printf("%s for %s complete", + async->op == STORE_OP_GET ? "GET" + : async->op == STORE_OP_PUT ? "PUT" + : async->op == STORE_OP_DELETE ? "DELETE" + : async->op == STORE_OP_BARRIER ? "BARRIER" : "???", + async->key) + ); + } + if (bluesky_verbose) { g_log("bluesky/store", G_LOG_LEVEL_DEBUG, "[%p] complete: elapsed = %"PRIi64" ns, latency = %"PRIi64" ns", @@ -255,6 +293,18 @@ void bluesky_store_async_submit(BlueSkyStoreAsync *async) // processing was started, if there could be a delay from submission time. async->exec_time = bluesky_now_hires(); + if (async->profile) { + bluesky_profile_add_event( + async->profile, + g_strdup_printf("Start %s for %s", + async->op == STORE_OP_GET ? "GET" + : async->op == STORE_OP_PUT ? "PUT" + : async->op == STORE_OP_DELETE ? "DELETE" + : async->op == STORE_OP_BARRIER ? "BARRIER" : "???", + async->key) + ); + } + if (bluesky_verbose) { g_log("bluesky/store", G_LOG_LEVEL_DEBUG, "[%p] submit: %s %s", async,