Пример #1
0
        public IDirectory RegisterDirectory(IDirectory directory)
        {
            cacheLock.EnterWriteLock();
            try
            {
                var blockId = directory.BlockId;
                if (openedDirectories.TryGetValue(blockId, out var directoryWithRefCount))
                {
                    var existingDirectory = Volatile.Read(ref directoryWithRefCount.Directory);
                    if (existingDirectory != null)
                    {
                        throw new InvalidOperationException($"Directory with blockId = {directory.BlockId} has already been registered");
                    }
                }

                directoryWithRefCount = new DirectoryWithRefCount
                {
                    Directory = directory,
                    RefCount  = 1
                };
                openedDirectories[blockId] = directoryWithRefCount;
                return(directory);
            }
            finally
            {
                cacheLock.ExitWriteLock();
            }
        }
Пример #2
0
        public IDirectory ReadDirectory(int blockId)
        {
            cacheLock.EnterUpgradeableReadLock();
            try
            {
                if (openedDirectories.TryGetValue(blockId, out var directoryWithRefCount))
                {
                    var directory = Volatile.Read(ref directoryWithRefCount.Directory);
                    if (directory != null)
                    {
                        Interlocked.Increment(ref directoryWithRefCount.RefCount);
                        return(directoryWithRefCount.Directory);
                    }
                }

                cacheLock.EnterWriteLock();
                try
                {
                    if (openedDirectories.TryGetValue(blockId, out directoryWithRefCount))
                    {
                        var directory = Volatile.Read(ref directoryWithRefCount.Directory);
                        if (directory != null)
                        {
                            Interlocked.Increment(ref directoryWithRefCount.RefCount);
                            return(directoryWithRefCount.Directory);
                        }
                    }

                    directoryWithRefCount = new DirectoryWithRefCount
                    {
                        Directory = unsafeDirectoryReader.Read(blockId),
                        RefCount  = 1
                    };
                    openedDirectories.Add(blockId, directoryWithRefCount);
                    return(directoryWithRefCount.Directory);
                }
                finally
                {
                    cacheLock.ExitWriteLock();
                }
            }
            finally
            {
                cacheLock.ExitUpgradeableReadLock();
            }
        }