//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test void countFlushesAndBytesWritten()
        internal virtual void CountFlushesAndBytesWritten()
        {
            PinEvent pinEvent = _pageCursorTracer.beginPin(true, 0, _swapper);

            {
                PageFaultEvent faultEvent = pinEvent.BeginPageFault();
                {
                    EvictionEvent evictionEvent = faultEvent.BeginEviction();
                    {
                        FlushEventOpportunity flushEventOpportunity = evictionEvent.FlushEventOpportunity();
                        {
                            FlushEvent flushEvent = flushEventOpportunity.BeginFlush(0, 0, _swapper);
                            flushEvent.AddBytesWritten(27);
                            flushEvent.Done();
                            FlushEvent flushEvent1 = flushEventOpportunity.BeginFlush(0, 1, _swapper);
                            flushEvent1.AddBytesWritten(13);
                            flushEvent1.Done();
                        }
                    }
                    evictionEvent.Close();
                }
                faultEvent.Done();
            }
            pinEvent.Done();

            assertEquals(1, _pageCursorTracer.pins());
            assertEquals(1, _pageCursorTracer.unpins());
            assertEquals(1, _pageCursorTracer.faults());
            assertEquals(1, _pageCursorTracer.evictions());
            assertEquals(2, _pageCursorTracer.flushes());
            assertEquals(40, _pageCursorTracer.bytesWritten());
        }
Beispiel #2
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private long cooperativelyEvict(org.neo4j.io.pagecache.tracing.PageFaultEvent faultEvent) throws java.io.IOException
        private long CooperativelyEvict(PageFaultEvent faultEvent)
        {
            int  iterations = 0;
            int  pageCount  = Pages.PageCount;
            int  clockArm   = ThreadLocalRandom.current().Next(pageCount);
            bool evicted    = false;
            long pageRef;

            do
            {
                AssertHealthy();
                if (FreelistHead != null)
                {
                    return(0);
                }

                if (clockArm == pageCount)
                {
                    if (iterations == _cooperativeEvictionLiveLockThreshold)
                    {
                        throw CooperativeEvictionLiveLock();
                    }
                    iterations++;
                    clockArm = 0;
                }

                pageRef = Pages.deref(clockArm);
                if (Pages.isLoaded(pageRef) && Pages.decrementUsage(pageRef))
                {
                    evicted = Pages.tryEvict(pageRef, faultEvent);
                }
                clockArm++;
            } while (!evicted);
            return(pageRef);
        }
        private void PinFaultAndHit()
        {
            PinEvent       pinEvent       = _pageCursorTracer.beginPin(true, 0, _swapper);
            PageFaultEvent pageFaultEvent = pinEvent.BeginPageFault();

            pinEvent.Hit();
            pageFaultEvent.Done();
            pinEvent.Done();
        }
Beispiel #4
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private long pageFault(long filePageId, org.neo4j.io.pagecache.PageSwapper swapper, long chunkOffset, int[] chunk, LatchMap.Latch latch) throws java.io.IOException
        private long PageFault(long filePageId, PageSwapper swapper, long chunkOffset, int[] chunk, LatchMap.Latch latch)
        {
            // We are page faulting. This is a critical time, because we currently have the given latch in the chunk array
            // slot that we are faulting into. We MUST make sure to release that latch, and remove it from the chunk, no
            // matter what happens. Otherwise other threads will get stuck waiting forever for our page fault to finish.
            // If we manage to get a free page to fault into, then we will also be taking a write lock on that page, to
            // protect it against concurrent eviction as we assigning a binding to the page. If anything goes wrong, then
            // we must make sure to release that write lock as well.
            PageFaultEvent faultEvent = PinEvent.beginPageFault();
            long           pageRef;

            try
            {
                // The grabFreePage method might throw.
                pageRef = PagedFile.grabFreeAndExclusivelyLockedPage(faultEvent);

                // We got a free page, and we know that we have race-free access to it. Well, it's not entirely race
                // free, because other paged files might have it in their translation tables (or rather, their reads of
                // their translation tables might race with eviction) and try to pin it.
                // However, they will all fail because when they try to pin, because the page will be exclusively locked
                // and possibly bound to our page.
            }
            catch (Exception throwable)
            {
                // Make sure to unstuck the page fault latch.
                AbortPageFault(throwable, chunk, chunkOffset, latch, faultEvent);
                throw throwable;
            }
            try
            {
                // Check if we're racing with unmapping. We have the page lock
                // here, so the unmapping would have already happened. We do this
                // check before page.fault(), because that would otherwise reopen
                // the file channel.
                AssertPagedFileStillMappedAndGetIdOfLastPage();
                PagedFile.initBuffer(pageRef);
                PagedFile.fault(pageRef, swapper, PagedFile.swapperId, filePageId, faultEvent);
            }
            catch (Exception throwable)
            {
                // Make sure to unlock the page, so the eviction thread can pick up our trash.
                PagedFile.unlockExclusive(pageRef);
                // Make sure to unstuck the page fault latch.
                AbortPageFault(throwable, chunk, chunkOffset, latch, faultEvent);
                throw throwable;
            }
            // Put the page in the translation table before we undo the exclusive lock, as we could otherwise race with
            // eviction, and the onEvict callback expects to find a MuninnPage object in the table.
            UnsafeUtil.putIntVolatile(chunk, chunkOffset, PagedFile.toId(pageRef));
            // Once we page has been published to the translation table, we can convert our exclusive lock to whatever we
            // need for the page cursor.
            ConvertPageFaultLock(pageRef);
            latch.Release();
            faultEvent.Done();
            return(pageRef);
        }
        private void GenerateEventSet()
        {
            PinEvent pinEvent = _pageCursorTracer.beginPin(false, 0, _swapper);

            {
                PageFaultEvent pageFaultEvent = pinEvent.BeginPageFault();
                pageFaultEvent.AddBytesRead(150);
                {
                    EvictionEvent evictionEvent = pageFaultEvent.BeginEviction();
                    {
                        FlushEventOpportunity flushEventOpportunity = evictionEvent.FlushEventOpportunity();
                        FlushEvent            flushEvent            = flushEventOpportunity.BeginFlush(0, 0, _swapper);
                        flushEvent.AddBytesWritten(10);
                        flushEvent.Done();
                    }
                    evictionEvent.ThrewException(new IOException("eviction exception"));
                    evictionEvent.Close();
                }
                pageFaultEvent.Done();
            }
            pinEvent.Done();
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test void countPageEvictions()
        internal virtual void CountPageEvictions()
        {
            PinEvent pinEvent = _pageCursorTracer.beginPin(true, 0, _swapper);

            {
                PageFaultEvent faultEvent = pinEvent.BeginPageFault();
                {
                    EvictionEvent evictionEvent = faultEvent.BeginEviction();
                    evictionEvent.FilePageId  = 0;
                    evictionEvent.CachePageId = 0;
                    evictionEvent.ThrewException(new IOException("exception"));
                    evictionEvent.Close();
                }
                faultEvent.Done();
            }
            pinEvent.Done();

            assertEquals(1, _pageCursorTracer.pins());
            assertEquals(1, _pageCursorTracer.unpins());
            assertEquals(1, _pageCursorTracer.faults());
            assertEquals(1, _pageCursorTracer.evictions());
            assertEquals(1, _pageCursorTracer.evictionExceptions());
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test void countPageFaultsAndBytesRead()
        internal virtual void CountPageFaultsAndBytesRead()
        {
            PinEvent pinEvent = _pageCursorTracer.beginPin(true, 0, _swapper);

            {
                PageFaultEvent pageFaultEvent = pinEvent.BeginPageFault();
                {
                    pageFaultEvent.AddBytesRead(42);
                }
                pageFaultEvent.Done();
                pageFaultEvent = pinEvent.BeginPageFault();
                {
                    pageFaultEvent.AddBytesRead(42);
                }
                pageFaultEvent.Done();
            }
            pinEvent.Done();

            assertEquals(1, _pageCursorTracer.pins());
            assertEquals(1, _pageCursorTracer.unpins());
            assertEquals(2, _pageCursorTracer.faults());
            assertEquals(84, _pageCursorTracer.bytesRead());
        }
Beispiel #8
0
 private void AbortPageFault(Exception throwable, int[] chunk, long chunkOffset, LatchMap.Latch latch, PageFaultEvent faultEvent)
 {
     UnsafeUtil.putIntVolatile(chunk, chunkOffset, UNMAPPED_TTE);
     latch.Release();
     faultEvent.Done(throwable);
     PinEvent.done();
 }
Beispiel #9
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: void fault(long pageRef, org.neo4j.io.pagecache.PageSwapper swapper, int swapperId, long filePageId, org.neo4j.io.pagecache.tracing.PageFaultEvent event) throws java.io.IOException
        internal virtual void Fault(long pageRef, PageSwapper swapper, int swapperId, long filePageId, PageFaultEvent @event)
        {
            if (swapper == null)
            {
                throw SwapperCannotBeNull();
            }
            int  currentSwapper    = GetSwapperId(pageRef);
            long currentFilePageId = GetFilePageId(pageRef);

            if (filePageId == PageCursor.UNBOUND_PAGE_ID || !IsExclusivelyLocked(pageRef) || currentSwapper != 0 || currentFilePageId != PageCursor.UNBOUND_PAGE_ID)
            {
                throw CannotFaultException(pageRef, swapper, swapperId, filePageId, currentSwapper, currentFilePageId);
            }
            // Note: It is important that we assign the filePageId before we swap
            // the page in. If the swapping fails, the page will be considered
            // loaded for the purpose of eviction, and will eventually return to
            // the freelist. However, because we don't assign the swapper until the
            // swapping-in has succeeded, the page will not be considered bound to
            // the file page, so any subsequent thread that finds the page in their
            // translation table will re-do the page fault.
            SetFilePageId(pageRef, filePageId);                 // Page now considered isLoaded()
            long bytesRead = swapper.Read(filePageId, GetAddress(pageRef), _cachePageSize);

            @event.AddBytesRead(bytesRead);
            @event.CachePageId = ToId(pageRef);
            SetSwapperId(pageRef, swapperId);                 // Page now considered isBoundTo( swapper, filePageId )
        }
Beispiel #10
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: long grabFreeAndExclusivelyLockedPage(org.neo4j.io.pagecache.tracing.PageFaultEvent faultEvent) throws java.io.IOException
        internal virtual long GrabFreeAndExclusivelyLockedPage(PageFaultEvent faultEvent)
        {
            // Review the comment on the freelist field before making changes to
            // this part of the code.
            // Whatever the case, we're going to the head-pointer of the freelist,
            // and in doing so, we can discover a number of things.
            // We can discover a MuninnPage object, in which case we can try to
            // CAS the freelist pointer to the value of the MuninnPage.nextFree
            // pointer, and if this succeeds then we've grabbed that page.
            // We can discover a FreePage object, in which case we'll do a similar
            // dance by attempting to CAS the freelist to the FreePage objects next
            // pointer, and again, if we succeed then we've grabbed the MuninnPage
            // given by the FreePage object.
            // We can discover a null-pointer, in which case the freelist has just
            // been emptied for whatever it contained before. New FreePage objects
            // are eventually going to be added to the freelist, but we are not
            // going to wait around for that to happen. If the freelist is empty,
            // then we do our own eviction to get a free page.
            // If we find a FreePage object on the freelist, then it is important
            // to check and see if it is the shutdownSignal instance. If that's the
            // case, then the page cache has been shut down, and we should throw an
            // exception from our page fault routine.
            object current;

            for ( ;;)
            {
                AssertHealthy();
                current = FreelistHead;
                if (current == null)
                {
                    UnparkEvictor();
                    long pageRef = CooperativelyEvict(faultEvent);
                    if (pageRef != 0)
                    {
                        return(pageRef);
                    }
                }
                else if (current is AtomicInteger)
                {
                    int           pageCount = Pages.PageCount;
                    AtomicInteger counter   = ( AtomicInteger )current;
                    int           pageId    = counter.get();
                    if (pageId < pageCount && counter.compareAndSet(pageId, pageId + 1))
                    {
                        return(Pages.deref(pageId));
                    }
                    if (pageId >= pageCount)
                    {
                        CompareAndSetFreelistHead(current, null);
                    }
                }
                else if (current is FreePage)
                {
                    FreePage freePage = ( FreePage )current;
                    if (freePage == _shutdownSignal)
                    {
                        throw new System.InvalidOperationException("The PageCache has been shut down.");
                    }

                    if (CompareAndSetFreelistHead(freePage, freePage.NextConflict))
                    {
                        return(freePage.PageRef);
                    }
                }
            }
        }