Switch to 31-bit directory cookies and a separate hashtable for lookups.
[bluesky.git] / bluesky.h
index 40c989b..793daa4 100644 (file)
--- a/bluesky.h
+++ b/bluesky.h
@@ -65,23 +65,47 @@ typedef struct {
 
     /* File-specific fields */
     uint64_t size;
+    GArray *blocks;
 
     /* Directory-specific fields */
-    GSequence *dirents;
+    GSequence *dirents;         /* List of entries for READDIR */
+    GHashTable *dirhash;        /* Hash table by name for LOOKUP */
     uint64_t parent_inum;       /* inode for ".."; 0 if the root directory */
 } BlueSkyInode;
 
 /* A directory entry.  The name is UTF-8 and is a freshly-allocated string.
- * The name is hashed to a 64-bit value, and the directory entries are sorted
- * by hash value (the hash value can then be used as a cookie for resuming a
- * READDIR call). */
+ * Each directory entry is listed in two indices: dirents is indexed by cookie
+ * and dirhash by name.  The cookie is a randomly-assigned 32-bit value, unique
+ * within the directory, that remains unchanged until the entry is deleted.  It
+ * is used to provide a stable key for restarting a READDIR call. */
 typedef struct {
     gchar *name;
-    uint64_t hash;
+    uint32_t cookie;
     uint64_t inum;
-} BlueSkyDirent ;
+} BlueSkyDirent;
+
+/* File data is divided into fixed-size blocks (except the last block which may
+ * be short?).  These blocks are backed by storage in a key/value store, but
+ * may also be dirty if modifications have been made in-memory that have not
+ * been committed. */
+#define BLUESKY_BLOCK_SIZE 32768ULL
+#define BLUESKY_MAX_FILE_SIZE (BLUESKY_BLOCK_SIZE << 24)
+typedef enum {
+    BLUESKY_BLOCK_ZERO = 0,     /* Data is all zeroes, not explicitly stored */
+    BLUESKY_BLOCK_REF = 1,      /* Reference to key/value store, not cached */
+    BLUESKY_BLOCK_CACHED = 2,   /* Data is cached in memory, clean */
+    BLUESKY_BLOCK_DIRTY = 3,    /* Data needs to be committed to store */
+} BlueSkyBlockType;
+
+typedef struct {
+    BlueSkyBlockType type;
+    gchar *ref;                 /* Name of data block in the backing store */
+    gchar *data;                /* Pointer to data in memory */
+} BlueSkyBlock;
 
+BlueSkyFS *bluesky_new_fs(gchar *name);
 int64_t bluesky_get_current_time();
+void bluesky_inode_update_ctime(BlueSkyInode *inode, gboolean update_mtime);
 uint64_t bluesky_fs_alloc_inode(BlueSkyFS *fs);
 BlueSkyInode *bluesky_new_inode(uint64_t inum, BlueSkyFileType type);
 
@@ -95,4 +119,6 @@ gboolean bluesky_directory_insert(BlueSkyInode *dir, gchar *name,
                                   uint64_t inum);
 void bluesky_directory_dump(BlueSkyInode *dir);
 
+void bluesky_file_truncate(BlueSkyInode *inode, uint64_t size);
+
 #endif