internal ProtoOwner(byte[] array, int offset, ProtoLRUCache parent, BlockIdentifier bid) { _array = array; _offset = offset; _parent = parent; _bid = bid; }
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); } } }
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); }
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)); }
public ProtoBlock(BlockIdentifier id, int offset) { BlockId = id; Offset = offset; }