예제 #1
0
        // 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.");
                }
            }
        }