Improve tracking of memory usage in BlueSky.
[bluesky.git] / bluesky / bluesky-private.h
index a265796..643092b 100644 (file)
@@ -44,7 +44,7 @@ BlueSkyInode *bluesky_list_tail(GList *head);
  * persistent storage. */
 void bluesky_serialize_superblock(GString *out, BlueSkyFS *fs);
 BlueSkyFS *bluesky_deserialize_superblock(const gchar *buf);
-void bluesky_serialize_inode(GString *out, BlueSkyInode *inode);
+BlueSkyCloudLog *bluesky_serialize_inode(BlueSkyInode *inode);
 gboolean bluesky_deserialize_inode(BlueSkyInode *inode, const gchar *buf);
 
 /* Storage layer.  Requests can be performed asynchronously, so these objects
@@ -142,9 +142,9 @@ void bluesky_store_add_barrier(BlueSkyStoreAsync *barrier,
 void bluesky_inode_start_sync(BlueSkyInode *inode);
 
 void bluesky_block_touch(BlueSkyInode *inode, uint64_t i);
-void bluesky_block_fetch(BlueSkyFS *fs, BlueSkyBlock *block,
+void bluesky_block_fetch(BlueSkyInode *inode, BlueSkyBlock *block,
                          BlueSkyStoreAsync *barrier);
-void bluesky_block_flush(BlueSkyFS *fs, BlueSkyBlock *block,
+void bluesky_block_flush(BlueSkyInode *inode, BlueSkyBlock *block,
                          GList **log_items);
 void bluesky_file_flush(BlueSkyInode *inode, GList **log_items);
 void bluesky_file_drop_cached(BlueSkyInode *inode);
@@ -165,6 +165,7 @@ typedef struct {
 } BlueSkyCloudPointer;
 
 typedef enum {
+    LOGTYPE_INVALID = -1,
     LOGTYPE_UNKNOWN = 0,
     LOGTYPE_DATA = 1,
     LOGTYPE_INODE = 2,
@@ -176,9 +177,9 @@ typedef enum {
 /* A record which tracks an object which has been written to a local log,
  * cached, locally, and/or written to the cloud. */
 #define CLOUDLOG_JOURNAL    0x01
-#define CLOUDLOG_CACHE      0x02
-#define CLOUDLOG_CLOUD      0x04
-typedef struct {
+#define CLOUDLOG_CLOUD      0x02
+#define CLOUDLOG_CACHE      0x04
+struct _BlueSkyCloudLog {
     gint refcount;
     GMutex *lock;
     GCond *cond;
@@ -206,12 +207,17 @@ typedef struct {
     // TODO: Location in journal/cache
     int log_seq, log_offset, log_size;
 
-    // Pointers to other objects
-    GArray *pointers;
+    // Pointers to other objects.  Each link counts towards the reference count
+    // of the pointed-to object.  To avoid memory leaks there should be no
+    // cycles in the reference graph.
+    GArray *links;
 
-    // Serialized data, if available in memory (otherwise NULL).
+    // Serialized data, if available in memory (otherwise NULL), and a lock
+    // count which tracks if there are users that require the data to be kept
+    // around.
     BlueSkyRCStr *data;
-} BlueSkyCloudLog;
+    int data_lock_count;
+};
 
 /* Serialize objects into a log segment to be written to the cloud. */
 struct _BlueSkyCloudLogState {
@@ -227,9 +233,13 @@ gchar *bluesky_cloudlog_id_to_string(BlueSkyCloudID id);
 BlueSkyCloudID bluesky_cloudlog_id_from_string(const gchar *idstr);
 void bluesky_cloudlog_ref(BlueSkyCloudLog *log);
 void bluesky_cloudlog_unref(BlueSkyCloudLog *log);
+void bluesky_cloudlog_stats_update(BlueSkyCloudLog *log, int type);
 void bluesky_cloudlog_sync(BlueSkyCloudLog *log);
 void bluesky_cloudlog_insert(BlueSkyCloudLog *log);
-void bluesky_cloudlog_write_log(BlueSkyFS *fs);
+void bluesky_cloudlog_fetch(BlueSkyCloudLog *log);
+BlueSkyCloudPointer bluesky_cloudlog_serialize(BlueSkyCloudLog *log,
+                                               BlueSkyFS *fs);
+void bluesky_cloudlog_flush(BlueSkyFS *fs);
 
 /* Logging infrastructure for ensuring operations are persistently recorded to
  * disk. */
@@ -240,13 +250,32 @@ uint32_t crc32c_finalize(uint32_t crc);
 struct _BlueSkyLog {
     char *log_directory;
     GAsyncQueue *queue;
-    int fd;
+    int fd, dirfd;
     int seq_num;
+    GSList *committed;
+
+    /* Cache of log segments which have been memory-mapped. */
+    GMutex *mmap_lock;
+    GHashTable *mmap_cache;
+};
+
+/* Reference-counted blocks of memory, used for passing data in and out of
+ * storage backends and in other places.  This may also refer to read-only
+ * mmaped data. */
+struct _BlueSkyMmap {
+    gint refcount;
+    int log_seq;
+    const char *addr;
+    size_t len;
+    BlueSkyLog *log;
 };
 
 BlueSkyLog *bluesky_log_new(const char *log_directory);
 void bluesky_log_item_submit(BlueSkyCloudLog *item, BlueSkyLog *log);
 void bluesky_log_finish_all(GList *log_items);
+BlueSkyRCStr *bluesky_log_map_object(BlueSkyLog *log, int log_seq,
+                                     int log_offset, int log_size);
+void bluesky_mmap_unref(BlueSkyMmap *mmap);
 
 #ifdef __cplusplus
 }