Add a prefetch method. At the moment it is a no-op.
[bluesky.git] / bluesky / cloudlog.c
index b2f95c7..7730d0e 100644 (file)
@@ -268,6 +268,16 @@ BlueSkyCloudLog *bluesky_cloudlog_get(BlueSkyFS *fs, BlueSkyCloudID id)
     return item;
 }
 
+/* Attempt to prefetch a cloud log item.  This does not guarantee that it will
+ * be made available, but does make it more likely that a future call to
+ * bluesky_cloudlog_fetch will complete quickly. */
+void bluesky_cloudlog_prefetch(BlueSkyCloudLog *log)
+{
+    gchar *id = bluesky_cloudlog_id_to_string(log->id);
+    g_print("Prefetch for %s\n", id);
+    g_free(id);
+}
+
 /* Ensure that a cloud log item is loaded in memory, and if not read it in.
  * TODO: Make asynchronous, and make this also fetch from the cloud.  Right now
  * we only read from the log.  Log item must be locked. */
@@ -283,49 +293,15 @@ void bluesky_cloudlog_fetch(BlueSkyCloudLog *log)
      * Once that is done, we can fall through the case of remapping the data
      * itself. */
     if (log->type == LOGTYPE_UNKNOWN) {
-        bluesky_cloudlog_stats_update(log, -1);
-        BlueSkyRCStr *raw = NULL;
-        if ((log->location_flags | log->pending_write) & CLOUDLOG_JOURNAL) {
-            raw = bluesky_log_map_object(log->fs, -1, log->log_seq,
-                                         log->log_offset, log->log_size);
-        }
-
-        if (raw == NULL && (log->location_flags & CLOUDLOG_CLOUD)) {
-            log->location_flags &= ~CLOUDLOG_JOURNAL;
-            raw = bluesky_log_map_object(log->fs,
-                                         log->location.directory,
-                                         log->location.sequence,
-                                         log->location.offset,
-                                         log->location.size);
-        }
-
+        BlueSkyRCStr *raw = bluesky_log_map_object(log, FALSE);
         g_assert(raw != NULL);
         bluesky_deserialize_cloudlog(log, raw->data, raw->len);
         bluesky_string_unref(raw);
-        bluesky_cloudlog_stats_update(log, 1);
     }
 
     /* At this point all metadata should be available and we need only remap
      * the object data. */
-
-    int offset;
-    if ((log->location_flags | log->pending_write) & CLOUDLOG_JOURNAL) {
-        bluesky_cloudlog_stats_update(log, -1);
-        offset = log->log_offset + sizeof(struct log_header);
-        log->data = bluesky_log_map_object(log->fs, -1, log->log_seq,
-                                           offset, log->data_size);
-        bluesky_cloudlog_stats_update(log, 1);
-    }
-
-    if (log->data == NULL && (log->location_flags & CLOUDLOG_CLOUD)) {
-        log->location_flags &= ~CLOUDLOG_JOURNAL;
-        bluesky_cloudlog_stats_update(log, -1);
-        offset = log->location.offset + sizeof(struct cloudlog_header);
-        log->data = bluesky_log_map_object(log->fs, log->location.directory,
-                                           log->location.sequence,
-                                           offset, log->data_size);
-        bluesky_cloudlog_stats_update(log, 1);
-    }
+    log->data = bluesky_log_map_object(log, TRUE);
 
     if (log->data == NULL) {
         g_error("Unable to fetch cloudlog entry!");
@@ -392,6 +368,7 @@ BlueSkyCloudPointer bluesky_cloudlog_serialize(BlueSkyCloudLog *log,
         g_mutex_lock(fs->lock);
         InodeMapEntry *entry = bluesky_inode_map_lookup(fs->inode_map,
                                                         log->inum, 1);
+        bluesky_cloudlog_unref_delayed(entry->item);
         entry->item = log;
         bluesky_cloudlog_ref(entry->item);
         g_mutex_unlock(fs->lock);
@@ -516,12 +493,15 @@ void bluesky_cloudlog_encrypt(GString *segment, BlueSkyCryptKeys *keys)
 }
 
 /* Make an decryption pass over a cloud log segment to decrypt items which were
- * encrypted.  TODO: Also computes a list of all offsets which at which valid
- * cloud log items are found. */
-void bluesky_cloudlog_decrypt(char *segment, size_t len, BlueSkyCryptKeys *keys)
+ * encrypted.  Also computes a list of all offsets which at which valid
+ * cloud log items are found and adds those offsets to items (if non-NULL). */
+void bluesky_cloudlog_decrypt(char *segment, size_t len,
+                              BlueSkyCryptKeys *keys,
+                              BlueSkyRangeset *items)
 {
     char *data = segment;
     size_t remaining_size = len;
+    size_t offset = 0;
 
     while (remaining_size >= sizeof(struct cloudlog_header)) {
         struct cloudlog_header *header = (struct cloudlog_header *)data;
@@ -532,11 +512,21 @@ void bluesky_cloudlog_decrypt(char *segment, size_t len, BlueSkyCryptKeys *keys)
         if (item_size > remaining_size)
             break;
         if (bluesky_crypt_block_decrypt(data, item_size, keys)) {
-            g_print("Decrypted valid cloud log item at offset %zd\n",
-                    data - segment);
+            if (items != NULL) {
+                g_print("  data item at %zx\n", offset);
+                bluesky_rangeset_insert(items, offset, item_size,
+                                        GINT_TO_POINTER(TRUE));
+            }
+        } else {
+            g_warning("Unauthenticated data at offset %zd", offset);
+            if (items != NULL) {
+                bluesky_rangeset_insert(items, offset, item_size,
+                                        GINT_TO_POINTER(TRUE));
+            }
         }
 
         data += item_size;
+        offset += item_size;
         remaining_size -= item_size;
     }
 }