Exemplo n.º 1
0
        public IFile RegisterFile(IFile file)
        {
            cacheLock.EnterWriteLock();
            try
            {
                var blockId = file.BlockId;
                if (openedFiles.TryGetValue(blockId, out var fileWithRefCount))
                {
                    var existingFile = Volatile.Read(ref fileWithRefCount.File);
                    if (existingFile != null)
                    {
                        throw new InvalidOperationException($"File with blockId = {file.BlockId} has already been registered");
                    }
                }

                fileWithRefCount = new FileWithRefCount
                {
                    File     = file,
                    RefCount = 1
                };
                openedFiles[blockId] = fileWithRefCount;
                return(file);
            }
            finally
            {
                cacheLock.ExitWriteLock();
            }
        }
Exemplo n.º 2
0
        public IFile ReadFile(int blockId, Func <IFile> readFile)
        {
            cacheLock.EnterUpgradeableReadLock();
            try
            {
                if (openedFiles.TryGetValue(blockId, out var fileWithRefCount))
                {
                    var file = Volatile.Read(ref fileWithRefCount.File);
                    if (file != null)
                    {
                        Interlocked.Increment(ref fileWithRefCount.RefCount);
                        return(fileWithRefCount.File);
                    }
                }

                cacheLock.EnterWriteLock();
                try
                {
                    if (openedFiles.TryGetValue(blockId, out fileWithRefCount))
                    {
                        var file = Volatile.Read(ref fileWithRefCount.File);
                        if (file != null)
                        {
                            Interlocked.Increment(ref fileWithRefCount.RefCount);
                            return(fileWithRefCount.File);
                        }
                    }

                    fileWithRefCount = new FileWithRefCount
                    {
                        File     = readFile(),
                        RefCount = 1
                    };
                    openedFiles.Add(blockId, fileWithRefCount);
                    return(fileWithRefCount.File);
                }
                finally
                {
                    cacheLock.ExitWriteLock();
                }
            }
            finally
            {
                cacheLock.ExitUpgradeableReadLock();
            }
        }