Add proper per-file copyright notices/licenses and top-level license.
[bluesky.git] / bluesky / store.c
index c2bb95e..ac9bc96 100644 (file)
@@ -3,7 +3,29 @@
  * Copyright (C) 2009  The Regents of the University of California
  * Written by Michael Vrable <mvrable@cs.ucsd.edu>
  *
- * TODO: Licensing
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #include <stdint.h>
@@ -105,11 +127,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 +243,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 +278,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 +315,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,