Initial work on cloud log-structured storage.
[bluesky.git] / bluesky / cloudlog.c
1 /* Blue Sky: File Systems in the Cloud
2  *
3  * Copyright (C) 2009  The Regents of the University of California
4  * Written by Michael Vrable <mvrable@cs.ucsd.edu>
5  *
6  * TODO: Licensing
7  */
8
9 #include <stdint.h>
10 #include <glib.h>
11 #include <string.h>
12
13 #include "bluesky-private.h"
14
15 /* The locations hash table in the file system is used to map objects to their locations.  Objects are named using 128- */
16
17 typedef struct {
18     BlueSkyCloudID id;
19
20     BlueSkyCloudPointer *cloud_loc;
21 } BlueSkyLocationEntry;
22
23 BlueSkyCloudID bluesky_cloudlog_new_id()
24 {
25     BlueSkyCloudID id;
26     bluesky_crypt_random_bytes((uint8_t *)&id.bytes, sizeof(id));
27     return id;
28 }
29
30 gboolean bluesky_cloudlog_equal(gconstpointer a, gconstpointer b)
31 {
32     BlueSkyCloudID *id1 = (BlueSkyCloudID *)a, *id2 = (BlueSkyCloudID *)b;
33
34     return memcmp(id1, id2, sizeof(BlueSkyCloudID)) == 0;
35 }
36
37 guint bluesky_cloudlog_hash(gconstpointer a)
38 {
39     BlueSkyCloudID *id = (BlueSkyCloudID *)a;
40
41     // Assume that bits in the ID are randomly chosen so that any subset of the
42     // bits can be used as a hash key.
43     return *(guint *)(&id->bytes);
44 }
45
46 /* Formatting of cloud log segments.  This handles grouping items together
47  * before writing a batch to the cloud, handling indirection through items like
48  * the inode map, etc. */
49
50 BlueSkyCloudLog *bluesky_cloudlog_new(BlueSkyFS *fs)
51 {
52     BlueSkyCloudLog *log = g_new0(BlueSkyCloudLog, 1);
53
54     log->fs = fs;
55     log->type = LOGTYPE_UNKNOWN;
56     log->id = bluesky_cloudlog_new_id();
57     g_atomic_int_set(&log->refcount, 1);
58
59     return log;
60 }
61
62 void bluesky_cloudlog_ref(BlueSkyCloudLog *log)
63 {
64     g_atomic_int_inc(&log->refcount);
65 }
66
67 void bluesky_cloudlog_unref(BlueSkyCloudLog *log)
68 {
69     if (g_atomic_int_dec_and_test(&log->refcount)) {
70         g_print("Cloud log refcount dropped to zero.\n");
71     }
72 }
73
74 /* Start a write of the object to the local log. */
75 BlueSkyLogItem *bluesky_cloudlog_sync(BlueSkyCloudLog *log)
76 {
77     BlueSkyLogItem *log_item = bluesky_log_item_new();
78     log_item->key = g_strdup("cloudlog");
79     log_item->data = log->data;
80     bluesky_string_ref(log->data);
81     bluesky_log_item_submit(log_item, log->fs->log);
82     return log_item;
83 }
84
85 /* Add the given entry to the global hash table containing cloud log entries.
86  * Takes ownership of the caller's reference. */
87 void bluesky_cloudlog_insert(BlueSkyCloudLog *log)
88 {
89     g_mutex_lock(log->fs->lock);
90     g_hash_table_insert(log->fs->locations, &log->id, log);
91     g_mutex_unlock(log->fs->lock);
92 }