// TODO: This should be part of buffer pool class. // Ideally page manager shouldn't keep track of in memory-disk mappings. private async Task RecordUsageAndEvict(ulong pageId, ITransaction tran) { ulong[] pageIdsToEvict = this.bufferPool.GetEvictionPolicy().RecordUsageAndEvict(pageId).ToArray(); foreach (ulong pageIdToEvict in pageIdsToEvict) { if (tran.AmIHoldingALock(pageIdToEvict, out LockTypeEnum heldLockType)) { // If this page is needed for myself don't release the lock. // Just ignore for now. continue; } using (Releaser lckReleaser = await tran.AcquireLockWithCallerOwnership(pageIdToEvict, LockTypeEnum.Exclusive).ConfigureAwait(false)) { logger.LogDebug($"Evicting page {pageIdToEvict}"); IPage pageToEvict = this.bufferPool.GetPage(pageIdToEvict); // Somebody came before us and evicted the page. if (pageToEvict == null) { continue; } await this.FlushPage(pageToEvict).ConfigureAwait(false); bufferPool.EvictPage(pageToEvict.PageId(), pageToEvict.GetBufferPoolToken()); logger.LogDebug($"Page {pageIdToEvict} evicted from buffer pool and flushed to the disk."); } } }