コード例 #1
0
        /// <summary>
        /// Opens a file stream to the given asset
        /// </summary>
        /// <param name="id">The Id of the file</param>
        /// <param name="hash">The hash of the file</param>
        /// <returns>A read only file handle to the asset</returns>
        public FileStream GetReadFileStream(Guid id, string hash)
        {
            string path = Path.Combine(this.root, CacheFile.GetFolder(hash), CacheFile.GetFileName(id, hash));

            File.SetLastAccessTime(path, DateTime.Now);
            return(File.OpenRead(path));
        }
コード例 #2
0
        /// <summary>
        /// Walks through all assets in the file system and evicts any items that occur in the past
        /// to take the cache file system below the requested limit.
        /// This should only be called in a background thread since this is a time intensive operation.
        /// </summary>
        /// <param name="state">Ignored, object state</param>
        private void Evict(object state)
        {
            ulong cacheLimitBytes = (ulong)Settings.Default.MaxCacheSizeMB * 1048576;

            if (this.cacheSizeBytes < cacheLimitBytes)
            {
                // Cache isn't big enough to evict
                logger.Info(
                    "Cache isn't large enough to require eviction.  Max: {0} MB, Current: {1} MB",
                    Settings.Default.MaxCacheSizeMB,
                    this.cacheSizeBytes / 1048576);
                return;
            }

            logger.Warn(
                "Cache eviction is starting to prune.  Max: {0} MB, Current: {1} MB",
                Settings.Default.MaxCacheSizeMB,
                this.cacheSizeBytes / 1048576);

            List <CacheFile> fileData = this.EnumerateAllCacheFiles();

            // Run the list of elements and delete the files that were accessed the furthest in the past
            var filesSorted = from a in fileData
                              orderby a.LastAccessed ascending
                              select a;
            IEnumerator <CacheFile> fileEnumerator = filesSorted.GetEnumerator();

            fileEnumerator.MoveNext();

            // Delete files until we are within 90% of the limit
            while (this.cacheSizeBytes > (cacheLimitBytes * Settings.Default.CacheFreePercentage))
            {
                CacheFile file = fileEnumerator.Current;

                lock (this.cacheSizeBytesLock)
                {
                    this.cacheSizeBytes -= (ulong)file.Length;
                }

                logger.Warn(
                    "Deleting last accessed {1} file {0}",
                    file.LastAccessed,
                    CacheFile.GetFileName(file.Id, file.Hash));
                File.Delete(CacheFile.GetFullFilePath(this.root, file.Id, file.Hash));

                if (!fileEnumerator.MoveNext())
                {
                    // There are no more files to clean
                    break;
                }
            }

            logger.Warn(
                "Cache eviction is complete.  Max: {0} MB, Current: {1} MB",
                Settings.Default.MaxCacheSizeMB,
                this.cacheSizeBytes / 1048576);
            this.evictingCache = false;
        }
コード例 #3
0
        /// <summary>
        /// Moves the file from the incoming temporary folder and moves it to permanent storage.
        /// The file is automatically marked as recently accessed in order to prevent it from being evicted.
        /// </summary>
        /// <param name="id">The Id of the file</param>
        /// <param name="hash">The hash of the file</param>
        public void CompleteFile(Guid id, string hash)
        {
            string fileName = CacheFile.GetFileName(id, hash);

            string src  = Path.Combine(this.incoming, fileName);
            string dest = CacheFile.GetFullFilePath(this.root, id, hash);

            if (!Directory.Exists(Path.GetDirectoryName(dest)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(dest));
            }

            // For some reason the cache server is asking to overwrite the file,
            if (CacheFile.IsFileCached(this.root, id, hash))
            {
                File.Delete(CacheFile.GetFullFilePath(this.root, id, hash));
            }

            File.Move(src, dest);
            File.SetLastAccessTime(dest, DateTime.Now);

            FileInfo info = new FileInfo(dest);

            lock (this.cacheSizeBytesLock)
            {
                // Increment the cache size by adding a file
                this.cacheSizeBytes += (ulong)info.Length;
                int limit = Settings.Default.MaxCacheSizeMB * 1048576;

                // Check we haven't exceeded the cap
                if (this.cacheSizeBytes > (ulong)limit && !this.evictingCache)
                {
                    // We've exceeded the cache cap, request a cleanup
                    this.evictingCache = true;
                    ThreadPool.QueueUserWorkItem(new WaitCallback(this.Evict));
                }
            }

            // Store a hit on the ojbect
            File.SetLastAccessTime(dest, DateTime.Now);

            logger.Info(CultureInfo.CurrentCulture, "Moving {0} to permanent cache", fileName);
        }
コード例 #4
0
        /// <summary>
        /// Opens a file stream to the file that represents the temporary cache file.  The caller should
        /// close the file and then call CompleteFile to move it to permanent storage.
        /// </summary>
        /// <param name="id">The id of the file</param>
        /// <param name="hash">The hash of the file</param>
        /// <returns>A file stream to the temporary file</returns>
        public FileStream GetTemporaryFile(Guid id, string hash)
        {
            string path = Path.Combine(this.incoming, CacheFile.GetFileName(id, hash));

            return(File.OpenWrite(path));
        }
コード例 #5
0
 /// <summary>
 /// Returns the full path of a given file
 /// </summary>
 /// <param name="root">The root folder of the cache</param>
 /// <param name="id">The Id of the file</param>
 /// <param name="hash">The hash of the file</param>
 /// <returns>The full path of the file</returns>
 public static string GetFullFilePath(string root, Guid id, string hash)
 {
     return(Path.Combine(root, CacheFile.GetFolder(hash), CacheFile.GetFileName(id, hash)));
 }