首先完成replacer,因为没有上过最新的lru的课程,所以提前在leetCode上看了lru缓存的解法,然后结合了自己在操作系统上的内容。
首先明确:需要一个容器用于存储可用的frame。同理,不需要知道frame的内容是什么,只用存储frameId即可。
其次,Pin()和Unpin() 这两个函数的本质作用是将对应的frameId从存储id的容易中移出和加入。
对于Pin(),要注意在某以page的引用计数大于0时,就得调用,将存储该page的frame的ID从可用容器中移除,因为其无法被调用设计到的BufferPool函数有:NewPageIml(), FetchPgImp()。
Unpin()则是在frame存放page的引用计数变为0时就调用,因为该frame可以用于存放其他page了,涉及到的函数有:UnpinPgImp()、DeletePgImp()。
Victim(),则是进行策略的选择,按照所规定的lru法则,从容器中挑选出一个牺牲frame,返回,如果无可用,则返回false.
FetchPgImp(page_id): 要从磁盘中读取对应的数据,注意点在:
* 如果请求的page已经再buffer pool中,则将其pin,读取数据,然后立即返回
* 如果没有,则使用replacer获得可以被替换的frame,然后存入请求的page。包括以下的函数和该函数,我们获取frame时,都会首先从Buffer Pool的存储可用frame的容器中取得,如果该容器为空,那么则调用replacer进行替换策略,得到可被替换的frameID。
* 获得替换的frame,其实质时获得到了page,跟新pageId,从磁盘读取需求的内容,pin,最后返回。
UnpinPgImp(page_id, is_dirty):将page的引用技术归零。
FlushPgImp(page_id):将page的内容写回磁盘。
NewPgImp(page_id):注意如果无可用的frame时,需要寻找牺牲的frame时要调用replacer中的方法。
DeletePgImp(page_id):和replacer的Unpin类似,只是说再page的引用技术为0时,可以将对应的索引从page table中删除,对应pageid置零,所使用的frameId则可以回到空闲容器中。我认为此处不需要调用repalcer_的Unpin函数,因为当前frame已是空闲frame,而不是被占用的状态。
FlushAllPagesImpl()
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。