X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Fcloudlog.c;h=0668da7144bcab694078d34ace25f1a0c46aa0d5;hb=43b95b084f95a57e6a08ab986037c4d3a72d2052;hp=7730d0e3f48c28e9b0020ad0b16fa70038503113;hpb=7f47ef48ce38ab71fc414bee592a9078ed1c0a7a;p=bluesky.git diff --git a/bluesky/cloudlog.c b/bluesky/cloudlog.c index 7730d0e..0668da7 100644 --- a/bluesky/cloudlog.c +++ b/bluesky/cloudlog.c @@ -270,12 +270,66 @@ BlueSkyCloudLog *bluesky_cloudlog_get(BlueSkyFS *fs, BlueSkyCloudID id) /* 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) + * bluesky_cloudlog_fetch will complete quickly. Item must be locked? */ +void bluesky_cloudlog_prefetch(BlueSkyCloudLog *item) { - gchar *id = bluesky_cloudlog_id_to_string(log->id); - g_print("Prefetch for %s\n", id); - g_free(id); + if (item->data != NULL) + return; + + /* TODO: Some of the code here is duplicated with bluesky_log_map_object. + * Refactor to fix that. */ + BlueSkyFS *fs = item->fs; + BlueSkyCacheFile *map = NULL; + + /* First, check to see if the journal still contains a copy of the item and + * if so update the atime on the journal so it is likely to be kept around + * until we need it. */ + if ((item->location_flags | item->pending_write) & CLOUDLOG_JOURNAL) { + map = bluesky_cachefile_lookup(fs, -1, item->log_seq, TRUE); + if (map != NULL) { + map->atime = bluesky_get_current_time(); + bluesky_cachefile_unref(map); + g_mutex_unlock(map->lock); + return; + } + } + + item->location_flags &= ~CLOUDLOG_JOURNAL; + if (!(item->location_flags & CLOUDLOG_CLOUD)) + return; + + map = bluesky_cachefile_lookup(fs, + item->location.directory, + item->location.sequence, + FALSE); + if (map == NULL) + return; + + /* At this point, we have information about the log segment containing the + * item we need. If our item is already fetched, we have nothing to do + * except update the atime. If not, queue up a fetch of our object. */ + const BlueSkyRangesetItem *rangeitem; + rangeitem = bluesky_rangeset_lookup(map->items, + item->location.offset); + if (rangeitem == NULL) { + if (map->prefetches == NULL) + map->prefetches = bluesky_rangeset_new(); + + gchar *id = bluesky_cloudlog_id_to_string(item->id); + g_print("Need to prefetch %s\n", id); + g_free(id); + + bluesky_rangeset_insert(map->prefetches, + item->location.offset, + item->location.size, NULL); + + uint64_t start, length; + bluesky_rangeset_get_extents(map->prefetches, &start, &length); + g_print("Range to prefetch: %"PRIu64" + %"PRIu64"\n", start, length); + } + + bluesky_cachefile_unref(map); + g_mutex_unlock(map->lock); } /* Ensure that a cloud log item is loaded in memory, and if not read it in.