コード例 #1
0
        public async Task <ReserveSpaceResult> TryReserveSpace(CacheEntry cacheEntry, string contentType, int byteCount,
                                                               bool allowEviction, AsyncLockProvider writeLocks,
                                                               CancellationToken cancellationToken)
        {
            var shard          = Database.GetShardForKey(cacheEntry.RelativePath);
            var shardSizeLimit = Options.MaxCacheBytes / Database.GetShardCount();

            // When we're okay with deleting the database entry even though the file isn't written
            var farFuture = DateTime.UtcNow.AddHours(1);

            var maxAttempts = 30;

            for (var attempts = 0; attempts < maxAttempts; attempts++)
            {
                var recordCreated =
                    await Database.CreateRecordIfSpace(shard, cacheEntry.RelativePath,
                                                       contentType,
                                                       EstimateEntryBytesWithOverhead(byteCount),
                                                       farFuture,
                                                       AccessCounter.GetHash(cacheEntry.Hash),
                                                       shardSizeLimit);

                // Return true if we created the record
                if (recordCreated)
                {
                    return new ReserveSpaceResult()
                           {
                               Success = true
                           }
                }
                ;

                // We need to evict but we are not permitted
                if (!allowEviction)
                {
                    return new ReserveSpaceResult()
                           {
                               Success = false, Message = "Eviction disabled in sync mode"
                           }
                }
                ;

                var entryDiskSpace = EstimateEntryBytesWithOverhead(byteCount) +
                                     Database.EstimateRecordDiskSpace(cacheEntry.RelativePath.Length + (contentType?.Length ?? 0));

                var missingSpace = Math.Max(0, await Database.GetShardSize(shard) + entryDiskSpace - shardSizeLimit);
                // Evict space
                var evictResult = await EvictSpace(shard, missingSpace, writeLocks, cancellationToken);

                if (!evictResult.Success)
                {
                    return(evictResult); //We failed to evict enough space from the cache
                }
            }

            return(new ReserveSpaceResult()
            {
                Success = false, Message = $"Eviction worked but CreateRecordIfSpace failed {maxAttempts} times."
            });
        }
コード例 #2
0
 public Task MarkFileCreated(CacheEntry cacheEntry, string contentType, long recordDiskSpace, DateTime createdDate)
 {
     return(Database.UpdateCreatedDateAtomic(
                Database.GetShardForKey(cacheEntry.RelativePath),
                cacheEntry.RelativePath,
                contentType,
                EstimateEntryBytesWithOverhead(recordDiskSpace),
                createdDate,
                AccessCounter.GetHash(cacheEntry.Hash)));
 }