/// <summary> /// 获取缓冲项 /// </summary> /// <param name="pos"></param> /// <param name="flags"></param> /// <returns></returns> public BufferEntry GetEntry(PagePosition pos, BufferSeekFlags flags = BufferSeekFlags.None) { //获取或者新分配(创建)一个Buffer var buffer = GetOrCreateEntry(pos, flags); if (buffer == null) { return(buffer); } if (buffer.State == BufferState.NoneLoading) { //新buffer,未加载,加载页面,此时一定是自己获取了写锁 LoadBufferPage(buffer); lock (SyncRoot) { AddLRUEntry(buffer); return(buffer); } } return(buffer); }
/// <summary> /// 获取或创建页面缓冲 /// </summary> /// <param name="pos"></param> /// <param name="flags"></param> /// <returns></returns> public BufferEntry GetOrCreateEntry(PagePosition pos, BufferSeekFlags flags) { //缓冲区锁 Monitor.Enter(SyncRoot); //对应页的buffer不存在,创建,获取写锁(很快)阻塞读,释放缓冲区锁,返回去读取 if (!Buffers.TryGetValue(pos, out var buffer)) { buffer = CreateEntry(pos); buffer.Count++; buffer.Latch.EnterWriteScope(); Buffers[pos] = buffer; Monitor.Exit(SyncRoot); return(buffer); } //buffer对应的页是无须加载的状态,增加引用计数,移动LRU,返回 if (buffer.State != BufferState.NoneLoading) { buffer.Count++; if (!flags.HasFlag(BufferSeekFlags.NoLRU)) { MoveLRUEntry(buffer); } Monitor.Exit(SyncRoot); return(buffer); } //不等待页面加载,不增加引用计数 if (flags.HasFlag(BufferSeekFlags.NoWait)) { Monitor.Exit(SyncRoot); return(null); } //页面未加载,释放缓冲区锁 buffer.Count++; Monitor.Exit(SyncRoot); //等待加载完成 buffer.Latch.EnterReadScope(); buffer.Latch.ExitReadScope(); //加缓冲区锁,移动LRUList Monitor.Enter(SyncRoot); if (!flags.HasFlag(BufferSeekFlags.NoLRU)) { MoveLRUEntry(buffer); } Monitor.Exit(SyncRoot); return(buffer); }