+/* 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);
+}