예제 #1
0
 internal ProtoOwner(byte[] array, int offset, ProtoLRUCache parent, BlockIdentifier bid)
 {
     _array  = array;
     _offset = offset;
     _parent = parent;
     _bid    = bid;
 }
예제 #2
0
 internal void ReturnReference(BlockIdentifier bid)
 {
     lock (_lock)
     {
         if (!_lookup.TryGetValue(bid, out var node))
         {
             throw new NotImplementedException();
         }
         node.Value.RefCount--;
         if (node.Value.RefCount == 0)
         {
             _lruList.AddFirst(node);
         }
     }
 }
예제 #3
0
        public unsafe void ReadBlock(IntPtr buffer, BlockIdentifier bid)
        {
            if (!_overlappedStructs.TryDequeue(out var overLappedPointer))
            {
                overLappedPointer = Marshal.AllocHGlobal(Unsafe.SizeOf <OverlappedStruct>());
            }

            ref var overlapped = ref Unsafe.AsRef <OverlappedStruct>((void *)overLappedPointer);

            overlapped.hEvent       = IntPtr.Zero;
            overlapped.Internal     = IntPtr.Zero;
            overlapped.InternalHigh = IntPtr.Zero;
            overlapped.Offset       = bid.BlockId * FileConsts.PageSize;
            overlapped.OffsetHigh   = 0;
            overlapped.Pointer      = IntPtr.Zero;
            overlapped.FileId       = bid.FileId;
            overlapped.BlockId      = (int)bid.BlockId;
            overlapped.LevelId      = bid.LevelId;

            ReadFile(_fileHandle, (void *)buffer, FileConsts.PageSize, out var readBytes, overLappedPointer);
        }
예제 #4
0
        public async Task <IMemoryOwner <byte> > GetMemory(FileIdentifier fileId, int blockId)
        {
            var bid = new BlockIdentifier()
            {
                BlockId = (uint)blockId, FileId = (ushort)fileId.FileId, LevelId = (ushort)fileId.Level
            };
            LinkedListNode <ProtoBlock> node;
            ProtoBlock block  = null;
            var        lookup = _lookup;

            lock (_lock)
            {
                if (lookup.TryGetValue(bid, out node))
                {
                    if (node.Value.RefCount == 0)
                    {
                        _lruList.Remove(node);
                    }
                    node.Value.RefCount++;
                }
                else
                {
                    if (lookup.Count < _maxBlocks)
                    {
                        var offset = _currentOffset;
                        _currentOffset += FileConsts.PageSize;

                        block = new ProtoBlock(bid, offset);
                        node  = new LinkedListNode <ProtoBlock>(block);
                        lookup.Add(bid, node);
                    }
                    else
                    {
                        var lastNode = _lruList.Last;
                        if (lastNode == null)
                        {
                            Console.WriteLine("We ran out of space in the blockcache");
                            throw new NotImplementedException("We have no space at the inn, we need to figure out what we do here so we don't deadlock");
                        }
                        else
                        {
                            lookup.Remove(lastNode.Value.BlockId);
                            _lruList.RemoveLast();
                            block = new ProtoBlock(bid, lastNode.Value.Offset);
                            node  = new LinkedListNode <ProtoBlock>(block);
                            lookup.Add(bid, node);
                        }
                    }
                }
            }

            if (block != null)
            {
                _files[fileId].ReadBlock(IntPtr.Add(_gcHandle.AddrOfPinnedObject(), block.Offset), bid);
                ProtoEventSource.Log.ReportCacheMiss();
            }
            else
            {
                ProtoEventSource.Log.ReportCacheHit();
            }

            await node.Value.Task;

            return(new ProtoOwner(_pinnedSlab, node.Value.Offset, this, bid));
        }
예제 #5
0
 public ProtoBlock(BlockIdentifier id, int offset)
 {
     BlockId = id;
     Offset  = offset;
 }