diff --git a/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/FreePage.java b/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/FreePage.java index d7b35fa789781..e1c7fd40bdc55 100644 --- a/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/FreePage.java +++ b/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/FreePage.java @@ -19,6 +19,8 @@ */ package org.neo4j.io.pagecache.impl.muninn; +import java.util.concurrent.atomic.AtomicInteger; + /** * A free page in the MuninnPageCache.freelist. * @@ -28,16 +30,27 @@ final class FreePage { final long pageRef; int count; - FreePage next; + Object next; FreePage( long pageRef ) { this.pageRef = pageRef; } - void setNext( FreePage next ) + void setNext( Object next ) { this.next = next; - this.count = next == null ? 1 : 1 + next.count; + if ( next == null ) + { + count = 1; + } + else if ( next.getClass() == AtomicInteger.class ) + { + count = 1 + ((AtomicInteger) next).get(); + } + else + { + this.count = 1 + ((FreePage) next).count; + } } } diff --git a/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCache.java b/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCache.java index 5d941a127c250..5139afc861503 100644 --- a/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCache.java +++ b/community/io/src/main/java/org/neo4j/io/pagecache/impl/muninn/MuninnPageCache.java @@ -225,7 +225,7 @@ public MuninnPageCache( this.pages = new PageList( maxPages, cachePageSize, memoryManager, new SwapperSet(), victimPage ); - UnsafeUtil.putObjectVolatile( this, freelistOffset, new AtomicInteger() ); + setFreelistHead( new AtomicInteger() ); } private static void verifyHacks() @@ -760,10 +760,9 @@ private boolean compareAndSetFreelistHead( Object expected, Object update ) this, freelistOffset, expected, update ); } - private Object getAndSetFreelistHead( Object newFreelistHead ) + private void setFreelistHead( Object newFreelistHead ) { - return UnsafeUtil.getAndSetObject( - this, freelistOffset, newFreelistHead ); + UnsafeUtil.putObjectVolatile( this, freelistOffset, newFreelistHead ); } /** @@ -789,7 +788,7 @@ void continuouslySweepPages() // The last thing we do, is signalling the shutdown of the cache via // the freelist. This signal is looked out for in grabFreePage. - getAndSetFreelistHead( shutdownSignal ); + setFreelistHead( shutdownSignal ); } private int parkUntilEvictionRequired( int keepFree ) @@ -886,7 +885,11 @@ private void addFreePageToFreelist( long pageRef ) do { current = getFreelistHead(); - freePage.setNext( current instanceof FreePage ? (FreePage) current : null ); + if ( current instanceof AtomicInteger && ((AtomicInteger) current).get() >= pages.getPageCount() ) + { + current = null; + } + freePage.setNext( current ); } while ( !compareAndSetFreelistHead( current, freePage ) ); }