In-progress commit of online cleaner.
[bluesky.git] / bluesky / cleaner.c
diff --git a/bluesky/cleaner.c b/bluesky/cleaner.c
new file mode 100644 (file)
index 0000000..ca61d94
--- /dev/null
@@ -0,0 +1,68 @@
+/* Blue Sky: File Systems in the Cloud
+ *
+ * Copyright (C) 2010  The Regents of the University of California
+ * Written by Michael Vrable <mvrable@cs.ucsd.edu>
+ *
+ * TODO: Licensing
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <glib.h>
+#include <string.h>
+
+#include "bluesky-private.h"
+
+/* Proxy component of the file system cleaner.  This consists effectively of
+ * code for merging multiple versions of the file system logs: that generated
+ * by us and that generated by the in-cloud cleaner.  Other logic, such as for
+ * rewriting log segments where needed and deleting old segments, is handled by
+ * the in-cloud cleaner component. */
+
+/* Check the cleaner's logs to find the a more recent checkpoint record.  This
+ * should be called occasionally to see if the cleaner has done any work since
+ * our last check. */
+void bluesky_cleaner_find_checkpoint(BlueSkyFS *fs)
+{
+    char *prefix = g_strdup_printf("log-%08d", BLUESKY_CLOUD_DIR_CLEANER);
+    char *last_segment = bluesky_store_lookup_last(fs->store, prefix);
+    g_free(prefix);
+    if (last_segment == NULL)
+        return;
+
+    g_print("Last cloud log segment: %s\n", last_segment);
+    int seq = atoi(last_segment + 13);
+    g_free(last_segment);
+
+    if (seq <= fs->log_state->latest_cleaner_seq_seen)
+        return;
+
+    g_print("New log segment appeared in cleaner directory: %d\n", seq);
+
+    BlueSkyCacheFile *cachefile;
+    cachefile = bluesky_cachefile_lookup(fs, BLUESKY_CLOUD_DIR_CLEANER, seq,
+                                         TRUE);
+    while (!cachefile->complete)
+        g_cond_wait(cachefile->cond, cachefile->lock);
+
+    g_print("Downloaded latest cleaner segment.\n");
+
+    int64_t offset = -1, length = 0;
+    while (TRUE) {
+        const BlueSkyRangesetItem *item;
+        item = bluesky_rangeset_lookup_next(cachefile->items, offset + 1);
+        if (item == NULL)
+            break;
+        offset = item->start;
+        length = item->length;
+    }
+
+    if (length > 0) {
+        g_print("Last object: %"PRIu64" + %"PRIu64"\n", offset, length);
+    }
+
+    bluesky_cachefile_unref(cachefile);
+    g_mutex_unlock(cachefile->lock);
+}