/// <summary> /// Attempts to get the cache entry which was last stored for the given fingerprint /// </summary> public static async Task <Possible <CacheEntry?> > TryGetLatestCacheEntryAsync( this ITwoPhaseFingerprintStore store, LoggingContext loggingContext, ContentFingerprint fingerprint, DateTime?time = null) { // This method starts at a leaf time node and traverses up until a parent node // is found which has a corresponding cache entry. Then the children of that parent // node are iterated recursively (latest in time first) to find the node that closest in time // to the specified time parameter. This yields the cache entry added most recently. var node = new TimeTreeNode(time); while (node != null) { var getResult = await store.TryGetTemporalCacheEntryAsync(loggingContext, node, fingerprint); if (!getResult.Succeeded) { return(getResult); } else if (getResult.Result != null) { return(await TryGetLatestChildCacheEntryAsync(loggingContext, node, store, fingerprint, getResult)); } node = node.Parent; } return((CacheEntry?)null); }
/// <summary> /// Attempts to get the cache entry for the child which comes latest in time /// </summary> private static async Task <Possible <CacheEntry?> > TryGetLatestChildCacheEntryAsync( LoggingContext loggingContext, TimeTreeNode node, ITwoPhaseFingerprintStore store, ContentFingerprint fingerprint, Possible <CacheEntry?> fallbackResult) { var childNodes = node.Children; var children = childNodes.Select(childNode => store.TryGetTemporalCacheEntryAsync(loggingContext, childNode, fingerprint)).ToList(); var childResults = await Task.WhenAll(children); // In reverse order (i.e. later in time), check children to see which // one has results for (int i = childResults.Length - 1; i >= 0; i--) { var childResult = childResults[i]; var childNode = childNodes[i]; if (!childResult.Succeeded) { continue; } if (childResult.Result != null) { return(await TryGetLatestChildCacheEntryAsync( loggingContext, childNode, store, fingerprint, childResult)); } } return(fallbackResult); }