public AzureIndexInput(AzureDirectory azuredirectory, ICloudBlob blob) { _name = blob.Uri.Segments[blob.Uri.Segments.Length - 1]; _azureDirectory = azuredirectory ?? throw new ArgumentNullException(nameof(azuredirectory)); #if FULLDEBUG Trace.WriteLine($"opening {_name} "); #endif _fileMutex = SyncMutexManager.GrabMutex(_azureDirectory, _name); _fileMutex.WaitOne(); try { _blobContainer = azuredirectory.BlobContainer; _blob = blob; var fileName = _name; var fFileNeeded = false; if (!CacheDirectory.FileExists(fileName)) { fFileNeeded = true; } else { var cachedLength = CacheDirectory.FileLength(fileName); var hasMetadataValue = blob.Metadata.TryGetValue("CachedLength", out var blobLengthMetadata); var blobLength = blob.Properties.Length; if (hasMetadataValue) { long.TryParse(blobLengthMetadata, out blobLength); } var blobLastModifiedUtc = blob.Properties.LastModified.Value.UtcDateTime; if (blob.Metadata.TryGetValue("CachedLastModified", out var blobLastModifiedMetadata)) { if (long.TryParse(blobLastModifiedMetadata, out var longLastModified)) { blobLastModifiedUtc = new DateTime(longLastModified).ToUniversalTime(); } } if (cachedLength != blobLength) { fFileNeeded = true; } else { // cachedLastModifiedUTC was not ouputting with a date (just time) and the time was always off var unixDate = CacheDirectory.FileModified(fileName); var start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var cachedLastModifiedUtc = start.AddMilliseconds(unixDate).ToUniversalTime(); if (cachedLastModifiedUtc != blobLastModifiedUtc) { var timeSpan = blobLastModifiedUtc.Subtract(cachedLastModifiedUtc); if (timeSpan.TotalSeconds > 1) { fFileNeeded = true; } else { #if FULLDEBUG Trace.WriteLine(timeSpan.TotalSeconds); #endif // file not needed } } } } // if the file does not exist // or if it exists and it is older then the lastmodified time in the blobproperties (which always comes from the blob storage) if (fFileNeeded) { if (_azureDirectory.ShouldCompressFile(_name)) { InflateStream(fileName); } else { using (var fileStream = new StreamOutput(CacheDirectory.CreateOutput(fileName))) { // get the blob _blob.DownloadToStream(fileStream); fileStream.Flush(); #if FULLDEBUG Trace.WriteLine($"GET {_name} RETREIVED {fileStream.Length} bytes"); #endif } } // and open it as an input _indexInput = CacheDirectory.OpenInput(fileName); } else { #if FULLDEBUG Trace.WriteLine($"Using cached file for {_name}"); #endif // open the file in read only mode _indexInput = CacheDirectory.OpenInput(fileName); } } finally { _fileMutex.ReleaseMutex(); } }