1 /* Blue Sky: File Systems in the Cloud
3 * Copyright (C) 2009 The Regents of the University of California
4 * Written by Michael Vrable <mvrable@cs.ucsd.edu>
9 /* A stacked storage implementation which tries to improve performance by
10 * duplicating GET requests. Create using a name like "multi:s3" and each GET
11 * request will be translated into two GET requests to the "s3" backend. The
12 * first to complete will have its results returned. */
19 #include "bluesky-private.h"
24 static gpointer multistore_new(const gchar *path)
26 BlueSkyStore *base = bluesky_store_new(path);
28 g_warning("Unable to create base store %s for multirequest stacking.",
35 static void multistore_destroy(gpointer store)
37 bluesky_store_free(store);
40 static void multistore_completion_handler(BlueSkyStoreAsync *async,
41 BlueSkyStoreAsync *top_async)
43 g_mutex_lock(top_async->lock);
45 /* This might be the second request to finish; in that case we don't do
47 if (top_async->status == ASYNC_RUNNING) {
48 if (top_async->op == STORE_OP_GET) {
49 bluesky_string_unref(top_async->data);
50 top_async->data = async->data;
51 bluesky_string_ref(top_async->data);
53 top_async->result = async->result;
54 bluesky_store_async_mark_complete(top_async);
57 g_mutex_unlock(top_async->lock);
58 bluesky_store_async_unref(top_async);
61 static void multistore_submit(gpointer store, BlueSkyStoreAsync *async)
63 BlueSkyStore *base = (BlueSkyStore *)store;
65 g_return_if_fail(async->status == ASYNC_NEW);
66 g_return_if_fail(async->op != STORE_OP_NONE);
70 async->status = ASYNC_RUNNING;
71 async->exec_time = bluesky_now_hires();
72 for (int i = 0; i < 2; i++) {
73 BlueSkyStoreAsync *a = bluesky_store_async_new(base);
75 a->key = g_strdup(async->key);
76 bluesky_store_async_ref(async);
77 bluesky_store_async_add_notifier(a, (GFunc)multistore_completion_handler, async);
78 bluesky_store_async_submit(a);
79 bluesky_store_async_unref(a);
85 async->status = ASYNC_RUNNING;
86 async->exec_time = bluesky_now_hires();
88 bluesky_store_async_ref(async);
89 BlueSkyStoreAsync *a = bluesky_store_async_new(base);
91 a->key = g_strdup(async->key);
92 a->data = async->data;
93 bluesky_string_ref(a->data);
94 bluesky_store_async_add_notifier(a, (GFunc)multistore_completion_handler, async);
95 bluesky_store_async_submit(a);
96 bluesky_store_async_unref(a);
101 g_warning("Uknown operation type for multistore: %d\n", async->op);
102 bluesky_store_async_mark_complete(async);
107 static char *multistore_lookup_last(gpointer store, const char *prefix)
109 BlueSkyStore *base = (BlueSkyStore *)store;
110 return bluesky_store_lookup_last(base, prefix);
113 static void multistore_cleanup(gpointer store, BlueSkyStoreAsync *async)
117 static BlueSkyStoreImplementation store_impl = {
118 .create = multistore_new,
119 .destroy = multistore_destroy,
120 .submit = multistore_submit,
121 .cleanup = multistore_cleanup,
122 .lookup_last = multistore_lookup_last,
125 void bluesky_store_init_multi(void)
127 bluesky_store_register(&store_impl, "multi");