public Page EnterLatch(BufferEntry buffer, LatchFlags flags) { if (LatchLocks.TryGetValue(buffer.Position, out var latchLock)) { if (flags != latchLock.Flags) { throw new InvalidOperationException($"has hold a {flags} lactch of the buffer:{buffer.Position}!"); } return(buffer.Page); } switch (flags) { case LatchFlags.Read: LatchLocks[buffer.Position] = buffer.Latch.EnterReadScope(); break; case LatchFlags.RWRead: LatchLocks[buffer.Position] = buffer.Latch.EnterReadWriteScope(); break; case LatchFlags.Write: LatchLocks[buffer.Position] = buffer.Latch.EnterWriteScope(); break; } return(buffer.Page); }
public bool CheckLatch(BufferEntry buffer, LatchFlags flags) { if (!LatchLocks.TryGetValue(buffer.Position, out var latch)) { return(false); } switch (flags) { case LatchFlags.Write: return(latch.Flags == LatchFlags.Write || latch.Flags == LatchFlags.RWWrite); default: return(true); } }
/// <summary> /// thread unsafe /// </summary> public bool UpgrateWrite() { if (_release == UnReleased) { switch (Flags) { case LatchFlags.Write: case LatchFlags.RWWrite: return(true); case LatchFlags.RWRead: //don't wait var ok = Latch._internalLock.TryEnterWriteLock(0); Flags = ok ? LatchFlags.RWWrite : Flags; return(ok); default: throw new InvalidOperationException(); } } return(false); }
public Page EnterLatch(PagePosition page, LatchFlags flags) { if (LatchLocks.TryGetValue(page, out var latchLock)) { if (flags != latchLock.Flags) { throw new InvalidOperationException($"has hold a {flags} lactch of the buffer:{page}!"); } return((latchLock.Latch.Target as BufferEntry)?.Page); } var buffer = Buffers.GetEntry(page); if (buffer == null) { throw new NullReferenceException(nameof(buffer)); } switch (flags) { case LatchFlags.Read: LatchLocks[page] = buffer.Latch.EnterReadScope(); break; case LatchFlags.Write: LatchLocks[page] = buffer.Latch.EnterWriteScope(); break; case LatchFlags.RWRead: LatchLocks[page] = buffer.Latch.EnterReadWriteScope(); break; } return(buffer.Page); }
public Page EnterLatch(int fileId, long pageNumber, LatchFlags flags) { return(EnterLatch(new PagePosition(fileId, pageNumber), flags)); }
private Stack <TreePage> GetPagePathForKey(LowLevelTransaction lltx, Span <byte> key, ushort size, LatchFlags latchFlags = LatchFlags.Write) { var path = new Stack <TreePage>(); var buffer = lltx.Buffers.GetEntry(_root.FileId, _root.PageNumber); while (true) { var page = lltx.EnterLatch(buffer, latchFlags).AsTree(); ref var th = ref page.TreeHeader; if (th.IsLeaf) { if (th.FreeSize > size) { while (path.Count != 0) { lltx.ExitLatch(path.Pop().Position); } } path.Push(page); break; } else if (th.FreeSize > MaxBranchEntrySize) { while (path.Count != 0) { lltx.ExitLatch(path.Pop().Position); } } path.Push(page); buffer = lltx.Buffers.GetEntry(page.FindPage(key)); }
public LatchScope(LatchEntry latch, LatchFlags flags) { Flags = flags; Latch = latch ?? throw new ArgumentNullException(nameof(latch)); }