internal virtual void Vacuum(SwapperSet swappers) { if (FreelistHead is AtomicInteger && swappers.CountAvailableIds() > 200) { return; // We probably still have plenty of free pages left. Don't bother vacuuming just yet. } swappers.Vacuum(swapperIds => { int pageCount = Pages.PageCount; try { using (EvictionRunEvent evictions = _pageCacheTracer.beginPageEvictions(0)) { for (int i = 0; i < pageCount; i++) { long pageRef = Pages.deref(i); while (swapperIds.contains(Pages.getSwapperId(pageRef))) { if (Pages.tryEvict(pageRef, evictions)) { AddFreePageToFreelist(pageRef); break; } } } } } catch (IOException e) { throw new UncheckedIOException(e); } }); }
/// <summary> /// This copy-constructor is useful for classes that want to extend the {@code PageList} class to inline its fields. /// All data and state will be shared between this and the given {@code PageList}. This means that changing the page /// list state through one has the same effect as changing it through the other – they are both effectively the same /// object. /// </summary> /// <param name="pageList"> The {@code PageList} instance whose state to copy. </param> internal PageList(PageList pageList) { this._pageCount = pageList._pageCount; this._cachePageSize = pageList._cachePageSize; this._memoryAllocator = pageList._memoryAllocator; this._swappers = pageList._swappers; this._victimPageAddress = pageList._victimPageAddress; this._baseAddress = pageList._baseAddress; this._bufferAlignment = pageList._bufferAlignment; }
internal PageList(int pageCount, int cachePageSize, MemoryAllocator memoryAllocator, SwapperSet swappers, long victimPageAddress, long bufferAlignment) { this._pageCount = pageCount; this._cachePageSize = cachePageSize; this._memoryAllocator = memoryAllocator; this._swappers = swappers; this._victimPageAddress = victimPageAddress; long bytes = (( long )pageCount) * META_DATA_BYTES_PER_PAGE; this._baseAddress = memoryAllocator.AllocateAligned(bytes, Long.BYTES); this._bufferAlignment = bufferAlignment; ClearMemory(_baseAddress, pageCount); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test void veryLargePageListsMustBeFullyAccessible() internal virtual void VeryLargePageListsMustBeFullyAccessible() { // We need roughly 2 GiBs of memory for the meta-data here, which is why this is an IT and not a Test. // We add one extra page worth of data to the size here, to avoid ending up on a "convenient" boundary. int pageSize = ( int )ByteUnit.kibiBytes(8); long pageCacheSize = ByteUnit.gibiBytes(513) + pageSize; int pages = Math.toIntExact(pageCacheSize / pageSize); MemoryAllocator mman = MemoryAllocator.createAllocator("2 GiB", GlobalMemoryTracker.INSTANCE); SwapperSet swappers = new SwapperSet(); long victimPage = VictimPageReference.GetVictimPage(pageSize, GlobalMemoryTracker.INSTANCE); PageList pageList = new PageList(pages, pageSize, mman, swappers, victimPage, Long.BYTES); // Verify we end up with the correct number of pages. assertThat(pageList.PageCount, @is(pages)); // Spot-check the accessibility in the bulk of the pages. IntStream.range(0, pages / 32).parallel().forEach(id => verifyPageMetaDataIsAccessible(pageList, id * 32)); // Thoroughly check the accessibility around the tail end of the page list. IntStream.range(pages - 2000, pages).parallel().forEach(id => verifyPageMetaDataIsAccessible(pageList, id)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @BeforeEach void setUp() internal virtual void SetUp() { _set = new SwapperSet(); }