Add proper per-file copyright notices/licenses and top-level license.
[bluesky.git] / bluesky / cloudlog.c
index 3e30f02..dd16976 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 <stdio.h>
@@ -192,12 +214,6 @@ void bluesky_cloudlog_unref_delayed(BlueSkyCloudLog *log)
         g_async_queue_push(log->fs->unref_queue, log);
 }
 
-void bluesky_cloudlog_threads_init(BlueSkyFS *fs)
-{
-    fs->unref_queue = g_async_queue_new();
-    g_thread_create(cloudlog_unref_thread, fs->unref_queue, FALSE, NULL);
-}
-
 /* Erase the information contained within the in-memory cloud log
  * representation.  This does not free up the item itself, but frees the data
  * and references to other log items and resets the type back to unknown.  If
@@ -271,6 +287,25 @@ BlueSkyCloudLog *bluesky_cloudlog_get(BlueSkyFS *fs, BlueSkyCloudID id)
     return item;
 }
 
+/* Work to fetch a cloudlog item in a background thread.  The item will be
+ * locked while the fetch is in progress and unlocked when it completes. */
+static GThreadPool *fetch_pool;
+
+static void background_fetch_task(gpointer p, gpointer unused)
+{
+    BlueSkyCloudLog *item = (BlueSkyCloudLog *)p;
+
+    g_mutex_lock(item->lock);
+    g_mutex_unlock(item->lock);
+    bluesky_cloudlog_unref(item);
+}
+
+void bluesky_cloudlog_background_fetch(BlueSkyCloudLog *item)
+{
+    bluesky_cloudlog_ref(item);
+    g_thread_pool_push(fetch_pool, item, NULL);
+}
+
 /* Attempt to prefetch a cloud log item.  This does not guarantee that it will
  * be made available, but does make it more likely that a future call to
  * bluesky_cloudlog_fetch will complete quickly.  Item must be locked? */
@@ -279,6 +314,14 @@ void bluesky_cloudlog_prefetch(BlueSkyCloudLog *item)
     if (item->data != NULL)
         return;
 
+    /* When operating in a non log-structured mode, simply start a background
+     * fetch immediately when asked to prefetch. */
+    if (bluesky_options.disable_aggregation
+        || bluesky_options.disable_read_aggregation) {
+        bluesky_cloudlog_background_fetch(item);
+        return;
+    }
+
     /* TODO: Some of the code here is duplicated with bluesky_log_map_object.
      * Refactor to fix that. */
     BlueSkyFS *fs = item->fs;
@@ -635,3 +678,11 @@ void bluesky_cloudlog_decrypt(char *segment, size_t len,
         remaining_size -= item_size;
     }
 }
+
+void bluesky_cloudlog_threads_init(BlueSkyFS *fs)
+{
+    fs->unref_queue = g_async_queue_new();
+    g_thread_create(cloudlog_unref_thread, fs->unref_queue, FALSE, NULL);
+    fetch_pool = g_thread_pool_new(background_fetch_task, NULL, 40, FALSE,
+                                   NULL);
+}