Attempt at building with CMake.
[bluesky.git] / store.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.h"
14
15 /* Interaction with cloud storage.  We expose very simple GET/PUT style
16  * interface, which different backends can implement.  Available backends
17  * (will) include Amazon S3 and a simple local store for testing purposes. */
18
19 /* Create and return a new reference-counted string.  The reference count is
20  * initially one.  The newly-returned string takes ownership of the memory
21  * pointed at by data, and will call g_free on it when the reference count
22  * drops to zero. */
23 BlueSkyRCStr *bluesky_string_new(gpointer data, gsize len)
24 {
25     BlueSkyRCStr *string = g_new(BlueSkyRCStr, 1);
26     string->data = data;
27     string->len = len;
28     g_atomic_int_set(&string->refcount, 1);
29     return string;
30 }
31
32 void bluesky_string_ref(BlueSkyRCStr *string)
33 {
34     if (string == NULL)
35         return;
36
37     g_atomic_int_inc(&string->refcount);
38 }
39
40 void bluesky_string_unref(BlueSkyRCStr *string)
41 {
42     if (string == NULL)
43         return;
44
45     if (g_atomic_int_dec_and_test(&string->refcount)) {
46         g_free(string->data);
47         g_free(string);
48     }
49 }
50
51 /* Duplicate and return a new reference-counted string, containing a copy of
52  * the original data, with a reference count of 1.  As an optimization, if the
53  * passed-in string already has a reference count of 1, the original is
54  * returned.   Can be used to make a mutable copy of a shared string.  For this
55  * to truly be safe, it is probably needed that there be some type of lock
56  * protecting access to the string. */
57 BlueSkyRCStr *bluesky_string_dup(BlueSkyRCStr *string)
58 {
59     if (string == NULL)
60         return NULL;
61
62     if (g_atomic_int_dec_and_test(&string->refcount)) {
63         /* There are no other shared copies, so return this one. */
64         g_atomic_int_inc(&string->refcount);
65         return string;
66     } else {
67         return bluesky_string_new(g_memdup(string->data, string->len),
68                                   string->len);
69     }
70 }
71
72 /* Simple in-memory data store for test purposes. */
73 typedef struct {
74     GMutex *lock;
75
76     /* TODO: A hashtable isn't optimal for list queries... */
77     GHashTable *store;
78 } MemStore;
79
80 MemStore *memstore_new()
81 {
82     MemStore *store = g_new(MemStore, 1);
83     store->lock = g_mutex_new();
84     store->store = g_hash_table_new_full(g_str_hash, g_str_equal,
85                                          g_free,
86                                          (GDestroyNotify)bluesky_string_unref);
87
88     return store;
89 }
90
91 BlueSkyRCStr *memstore_get(MemStore *store, const gchar *key)
92 {
93     BlueSkyRCStr *s = g_hash_table_lookup(store->store, key);
94     if (s != NULL)
95         bluesky_string_ref(s);
96     return s;
97 }
98
99 void memstore_put(MemStore *store, const gchar *key, BlueSkyRCStr *val)
100 {
101     bluesky_string_ref(val);
102     g_hash_table_insert(store->store, g_strdup(key), val);
103 }