Convert rangeset implementation from a hashtable to GSequence.
[bluesky.git] / bluesky / log.c
index 8801b33..38606c1 100644 (file)
@@ -468,8 +468,14 @@ BlueSkyCacheFile *bluesky_cachefile_lookup(BlueSkyFS *fs,
     return map;
 }
 
+/* The arguments are mostly straightforward.  log_dir is -1 for access from the
+ * journal, and non-negative for access to a cloud log segment.  map_data
+ * should be TRUE for the case that are mapping just the data of an item where
+ * we have already parsed the item headers; this surpresses the error when the
+ * access is not to the first bytes of the item. */
 BlueSkyRCStr *bluesky_log_map_object(BlueSkyFS *fs, int log_dir,
-                                     int log_seq, int log_offset, int log_size)
+                                     int log_seq, int log_offset, int log_size,
+                                     gboolean map_data)
 {
     if (page_size == 0) {
         page_size = getpagesize();
@@ -485,9 +491,17 @@ BlueSkyRCStr *bluesky_log_map_object(BlueSkyFS *fs, int log_dir,
     /* Log segments fetched from the cloud might only be partially-fetched.
      * Check whether the object we are interested in is available. */
     if (log_dir >= 0) {
-        if (!bluesky_rangeset_lookup(map->items, log_offset)) {
+        const BlueSkyRangesetItem *rangeitem;
+        rangeitem = bluesky_rangeset_lookup(map->items, log_offset);
+        if (rangeitem == NULL || rangeitem->start != log_offset) {
             g_warning("log-%d: Item at offset %d does not seem to be available\n", log_seq, log_offset);
         }
+        if (map_data && rangeitem != NULL
+            && log_offset > rangeitem->start
+            && log_size <= rangeitem->length - (log_offset - rangeitem->start))
+        {
+            g_warning("  ...allowing access to middle of log item");
+        }
     }
 
     if (map->addr == NULL) {