Пример #1
0
        public CacheEntry CreateView(long offset, uint size, MemoryMappedFileAccess access)
        {
            if (_IsDisposed)
                throw new ObjectDisposedException("Cache");

            if (access == MemoryMappedFileAccess.Write)
                access = MemoryMappedFileAccess.ReadWrite;

            int? freeSlot = null;
            int? oldestUsedSlot = null;
            long oldestUsedTimestamp = long.MaxValue;

            for (int i = 0; i < Capacity; i++) {
                var item = Cache[i];

                if (item == null || item.IsDisposed) {
                    freeSlot = i;
                    continue;
                }

                if (item.CreatedWhen < oldestUsedTimestamp)
                    oldestUsedSlot = i;

                if (offset < item.Offset)
                    continue;
                if (offset + size > item.Offset + item.Size)
                    continue;

                if (item.AddRef())
                    return item;
                else {
                    freeSlot = i;
                    break;
                }
            }

            if (!freeSlot.HasValue && !oldestUsedSlot.HasValue)
                throw new InvalidDataException();

            long actualOffset;
            uint actualSize;
            var view = CreateViewUncached(offset, size, MemoryMappedFileAccess.ReadWrite, out actualOffset, out actualSize);

            var newEntry = new CacheEntry(view, actualOffset, actualSize);
            newEntry.AddRef();

            long slotIndex = freeSlot.GetValueOrDefault(oldestUsedSlot.GetValueOrDefault(0));
            var oldEntry = Interlocked.Exchange(ref Cache[slotIndex], newEntry);

            if (oldEntry != null)
                oldEntry.RemoveRef();

            return newEntry;
        }
Пример #2
0
        public CacheEntry CreateView(long offset, uint size, MemoryMappedFileAccess access)
        {
            if (_IsDisposed)
            {
                throw new ObjectDisposedException("Cache");
            }

            if (access == MemoryMappedFileAccess.Write)
            {
                access = MemoryMappedFileAccess.ReadWrite;
            }

            int? freeSlot            = null;
            int? oldestUsedSlot      = null;
            long oldestUsedTimestamp = long.MaxValue;

            for (int i = 0; i < Capacity; i++)
            {
                var item = Cache[i];

                if (item == null || item.IsDisposed)
                {
                    freeSlot = i;
                    continue;
                }

                if (item.CreatedWhen < oldestUsedTimestamp)
                {
                    oldestUsedSlot = i;
                }

                if (offset < item.Offset)
                {
                    continue;
                }
                if (offset + size > item.Offset + item.Size)
                {
                    continue;
                }

                if (item.AddRef())
                {
                    return(item);
                }
                else
                {
                    freeSlot = i;
                    break;
                }
            }

            if (!freeSlot.HasValue && !oldestUsedSlot.HasValue)
            {
                throw new InvalidDataException();
            }

            long actualOffset;
            uint actualSize;
            var  view = CreateViewUncached(offset, size, MemoryMappedFileAccess.ReadWrite, out actualOffset, out actualSize);

            var newEntry = new CacheEntry(view, actualOffset, actualSize);

            newEntry.AddRef();

            long slotIndex = freeSlot.GetValueOrDefault(oldestUsedSlot.GetValueOrDefault(0));
            var  oldEntry  = Interlocked.Exchange(ref Cache[slotIndex], newEntry);

            if (oldEntry != null)
            {
                oldEntry.RemoveRef();
            }

            return(newEntry);
        }