diff --git a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/ConsistencyCheckTasks.java b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/ConsistencyCheckTasks.java index a48827b29a2bf..92ac818fb42b9 100644 --- a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/ConsistencyCheckTasks.java +++ b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/ConsistencyCheckTasks.java @@ -39,7 +39,7 @@ import org.neo4j.helpers.progress.ProgressMonitorFactory; import org.neo4j.kernel.api.labelscan.LabelScanStore; import org.neo4j.kernel.impl.store.RecordStore; -import org.neo4j.kernel.impl.store.RecordStore.Scanner; +import org.neo4j.kernel.impl.store.Scanner; import org.neo4j.kernel.impl.store.SchemaStorage; import org.neo4j.kernel.impl.store.StoreAccess; import org.neo4j.kernel.impl.store.record.AbstractBaseRecord; diff --git a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/IterableStore.java b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/IterableStore.java index 4ac53635cc43e..601bb4d1527cd 100644 --- a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/IterableStore.java +++ b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/IterableStore.java @@ -29,7 +29,7 @@ import org.neo4j.kernel.impl.store.record.AbstractBaseRecord; import static org.neo4j.consistency.checking.full.CloningRecordIterator.cloned; -import static org.neo4j.kernel.impl.store.RecordStore.Scanner.scan; +import static org.neo4j.kernel.impl.store.Scanner.scan; import static org.neo4j.kernel.impl.store.record.RecordLoad.FORCE; public class IterableStore implements BoundedIterable diff --git a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/StoreProcessor.java b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/StoreProcessor.java index 04286b2d16e91..7397fff5e449e 100644 --- a/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/StoreProcessor.java +++ b/community/consistency-check/src/main/java/org/neo4j/consistency/checking/full/StoreProcessor.java @@ -47,7 +47,7 @@ import static org.neo4j.consistency.checking.cache.DefaultCacheAccess.DEFAULT_QUEUE_SIZE; import static org.neo4j.consistency.checking.full.CloningRecordIterator.cloned; import static org.neo4j.consistency.checking.full.RecordDistributor.distributeRecords; -import static org.neo4j.kernel.impl.store.RecordStore.Scanner.scan; +import static org.neo4j.kernel.impl.store.Scanner.scan; /** * Full check works by spawning StoreProcessorTasks that call StoreProcessor. StoreProcessor.applyFiltered() diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/RecordStore.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/RecordStore.java index e14289d33e604..9fbe55327eed0 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/RecordStore.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/RecordStore.java @@ -23,11 +23,9 @@ import java.util.Collection; import java.util.function.Predicate; -import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.helpers.progress.ProgressListener; import org.neo4j.graphdb.ResourceIterable; import org.neo4j.graphdb.ResourceIterator; -import org.neo4j.helpers.collection.PrefetchingResourceIterator; import org.neo4j.kernel.impl.store.id.IdType; import org.neo4j.io.pagecache.PageCursor; import org.neo4j.kernel.impl.store.id.IdSequence; @@ -470,58 +468,6 @@ private void apply( RecordStore store, Progres } } - class Scanner - { - @SafeVarargs - public static ResourceIterable scan( final RecordStore store, - final Predicate... filters ) - { - return scan( store, true, filters ); - } - - @SafeVarargs - public static ResourceIterable scan( final RecordStore store, - final boolean forward, final Predicate... filters ) - { - return () -> new PrefetchingResourceIterator() - { - final PrimitiveLongIterator ids = new StoreIdIterator( store, forward ); - final RecordCursor cursor = store.newRecordCursor( store.newRecord() ); - { - store.placeRecordCursor( 0, cursor, RecordLoad.CHECK ); - } - - @Override - protected R fetchNextOrNull() - { - scan: - while ( ids.hasNext() ) - { - if ( cursor.next( ids.next() ) ) - { - R record = cursor.get(); - for ( Predicate filter : filters ) - { - if ( !filter.test( record ) ) - { - continue scan; - } - } - return record; - } - } - return null; - } - - @Override - public void close() - { - cursor.close(); - } - }; - } - } - /** * Utility methods for reading records. These are not on the interface itself since it should be * an explicit choice when to create the record instances passed into it. diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/Scanner.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/Scanner.java new file mode 100644 index 0000000000000..02ad7b627bf27 --- /dev/null +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/Scanner.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2002-2016 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.store; + +import java.util.function.Predicate; + +import org.neo4j.collection.primitive.PrimitiveLongIterator; +import org.neo4j.graphdb.ResourceIterable; +import org.neo4j.graphdb.ResourceIterator; +import org.neo4j.helpers.collection.PrefetchingResourceIterator; +import org.neo4j.kernel.impl.store.record.AbstractBaseRecord; +import org.neo4j.kernel.impl.store.record.RecordLoad; + +/** + * Scans all used records in a store, returned {@link ResourceIterable} must be properly used such that + * its {@link ResourceIterable#iterator() resource iterators} are {@link ResourceIterator#close() closed} + * after use. + */ +public class Scanner +{ + @SafeVarargs + public static ResourceIterable scan( final RecordStore store, + final Predicate... filters ) + { + return scan( store, true, filters ); + } + + @SafeVarargs + public static ResourceIterable scan( final RecordStore store, + final boolean forward, final Predicate... filters ) + { + return () -> new Scan<>( store, forward, filters ); + } + + private static class Scan extends PrefetchingResourceIterator + { + private final PrimitiveLongIterator ids; + private final RecordCursor cursor; + private final Predicate[] filters; + + public Scan( RecordStore store, boolean forward, final Predicate... filters ) + { + this.filters = filters; + this.ids = new StoreIdIterator( store, forward ); + this.cursor = store.newRecordCursor( store.newRecord() ); + store.placeRecordCursor( 0, cursor, RecordLoad.CHECK ); + } + + @Override + protected R fetchNextOrNull() + { + while ( ids.hasNext() ) + { + if ( cursor.next( ids.next() ) ) + { + R record = cursor.get(); + if ( passesFilters( record ) ) + { + return record; + } + } + } + return null; + } + + private boolean passesFilters( R record ) + { + for ( Predicate filter : filters ) + { + if ( !filter.test( record ) ) + { + return false; + } + } + return true; + } + + @Override + public void close() + { + cursor.close(); + } + } +}