Skip to content

Commit

Permalink
Small refactor to allow adding more check types
Browse files Browse the repository at this point in the history
  • Loading branch information
davidegrohmann committed Dec 22, 2015
1 parent 64ba396 commit 569e4d4
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 216 deletions.
36 changes: 19 additions & 17 deletions tools/src/main/java/org/neo4j/tools/txlog/CheckTxLogs.java
Expand Up @@ -22,7 +22,6 @@
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;


import org.neo4j.helpers.Args; import org.neo4j.helpers.Args;
import org.neo4j.io.fs.DefaultFileSystemAbstraction; import org.neo4j.io.fs.DefaultFileSystemAbstraction;
Expand All @@ -35,18 +34,19 @@
import org.neo4j.kernel.impl.transaction.log.entry.LogEntry; import org.neo4j.kernel.impl.transaction.log.entry.LogEntry;
import org.neo4j.kernel.impl.transaction.log.entry.LogEntryCommand; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryCommand;
import org.neo4j.test.LogTestUtils; import org.neo4j.test.LogTestUtils;
import org.neo4j.tools.txlog.checktypes.CheckType;
import org.neo4j.tools.txlog.checktypes.CheckTypes;


/** /**
* Tool that verifies consistency of transaction logs. * Tool that verifies consistency of transaction logs.
* <p/> *
* Transaction log is considered consistent when every command's before state is the same as after state for * Transaction log is considered consistent when every command's before state is the same as after state for
* corresponding record in previously committed transaction. * corresponding record in previously committed transaction.
* <p/> *
* Tool expects a single argument - directory with transaction logs. * Tool expects a single argument - directory with transaction logs.
* It then simply iterates over all commands in those logs, compares before state for current record with previously * It then simply iterates over all commands in those logs, compares before state for current record with previously
* seen after state and stores after state for current record, if before state is consistent. * seen after state and stores after state for current record, if before state is consistent.
*/ */
//: TODO introduce abstract tool class as soon as we will have several tools in tools module
public class CheckTxLogs public class CheckTxLogs
{ {
private static final String HELP_FLAG = "help"; private static final String HELP_FLAG = "help";
Expand All @@ -72,12 +72,19 @@ public static void main( String[] args ) throws Exception


CheckTxLogs tool = new CheckTxLogs( new DefaultFileSystemAbstraction() ); CheckTxLogs tool = new CheckTxLogs( new DefaultFileSystemAbstraction() );


tool.scan( logs, CheckType.NODE, new PrintingInconsistenciesHandler() ); tool.scan( logs, new PrintingInconsistenciesHandler(), CheckTypes.CHECK_TYPES );
tool.scan( logs, CheckType.PROPERTY, new PrintingInconsistenciesHandler() );
} }


<C extends Command, R extends Abstract64BitRecord> void scan( File[] logs, CheckType<C,R> check, void scan( File[] logs, InconsistenciesHandler handler, CheckType<?,?>... checkTypes ) throws IOException
InconsistenciesHandler handler ) throws IOException {
for ( CheckType<?,?> checkType : checkTypes )
{
scan( logs, handler, checkType );
}
}

private <C extends Command, R extends Abstract64BitRecord> void scan(
File[] logs, InconsistenciesHandler handler, CheckType<C,R> check ) throws IOException
{ {
System.out.println( "Checking logs for " + check.name() + " inconsistencies" ); System.out.println( "Checking logs for " + check.name() + " inconsistencies" );


Expand Down Expand Up @@ -144,15 +151,10 @@ private static File parseDir( Args args )
private static File[] txLogsIn( File dir ) private static File[] txLogsIn( File dir )
{ {
File[] logs = dir.listFiles( LogFiles.FILENAME_FILTER ); File[] logs = dir.listFiles( LogFiles.FILENAME_FILTER );
Arrays.sort( logs, new Comparator<File>() Arrays.sort( logs, ( f1, f2 ) -> {
{ long f1Version = PhysicalLogFiles.getLogVersion( f1 );
@Override long f2Version = PhysicalLogFiles.getLogVersion( f2 );
public int compare( File f1, File f2 ) return Long.compare( f1Version, f2Version );
{
long f1Version = PhysicalLogFiles.getLogVersion( f1 );
long f2Version = PhysicalLogFiles.getLogVersion( f2 );
return Long.compare( f1Version, f2Version );
}
} ); } );
return logs; return logs;
} }
Expand Down
195 changes: 0 additions & 195 deletions tools/src/main/java/org/neo4j/tools/txlog/CheckType.java

This file was deleted.

Expand Up @@ -24,6 +24,7 @@
import org.neo4j.kernel.impl.store.record.Abstract64BitRecord; import org.neo4j.kernel.impl.store.record.Abstract64BitRecord;
import org.neo4j.kernel.impl.store.record.NodeRecord; import org.neo4j.kernel.impl.store.record.NodeRecord;
import org.neo4j.kernel.impl.store.record.PropertyRecord; import org.neo4j.kernel.impl.store.record.PropertyRecord;
import org.neo4j.tools.txlog.checktypes.CheckType;


/** /**
* Contains mapping from entity id ({@link NodeRecord#getId()}, {@link PropertyRecord#getId()}, ...) to * Contains mapping from entity id ({@link NodeRecord#getId()}, {@link PropertyRecord#getId()}, ...) to
Expand Down
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2002-2015 "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 Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.tools.txlog.checktypes;

import org.neo4j.kernel.impl.store.record.Abstract64BitRecord;
import org.neo4j.kernel.impl.transaction.command.Command;
import org.neo4j.kernel.impl.transaction.command.Command.NodeCommand;
import org.neo4j.kernel.impl.transaction.command.Command.PropertyCommand;

/**
* Type of command ({@link NodeCommand}, {@link PropertyCommand}, ...) to check during transaction log verification.
* This class exists to mitigate the absence of interfaces for commands with before and after state.
* It also provides an alternative equality check instead of {@link Abstract64BitRecord#equals(Object)} that only
* checks {@linkplain Abstract64BitRecord#getLongId() entity id}.
*
* @param <C> the type of command to check
* @param <R> the type of records that this command contains
*/
public abstract class CheckType<C extends Command, R extends Abstract64BitRecord>
{
private final Class<C> recordClass;

CheckType( Class<C> recordClass )
{
this.recordClass = recordClass;
}

public Class<C> commandClass()
{
return recordClass;
}

public abstract R before( C command );

public abstract R after( C command );

public abstract boolean equal( R record1, R record2 );

public abstract String name();
}
@@ -0,0 +1,14 @@
package org.neo4j.tools.txlog.checktypes;

import org.neo4j.kernel.impl.store.record.Abstract64BitRecord;
import org.neo4j.kernel.impl.transaction.command.Command;

public class CheckTypes
{
public static final NodeCheckType NODE = new NodeCheckType();
public static final PropertyCheckType PROPERTY = new PropertyCheckType();

@SuppressWarnings( "unchecked" )
public static final CheckType<? extends Command, ? extends Abstract64BitRecord>[] CHECK_TYPES =
new CheckType[]{NODE, PROPERTY};
}
@@ -0,0 +1,46 @@
package org.neo4j.tools.txlog.checktypes;

import java.util.Objects;

import org.neo4j.kernel.impl.store.record.NodeRecord;
import org.neo4j.kernel.impl.transaction.command.Command;

class NodeCheckType extends CheckType<Command.NodeCommand,NodeRecord>
{
NodeCheckType()
{
super( Command.NodeCommand.class );
}

@Override
public NodeRecord before( Command.NodeCommand command )
{
return command.getBefore();
}

@Override
public NodeRecord after( Command.NodeCommand command )
{
return command.getAfter();
}

@Override
public boolean equal( NodeRecord record1, NodeRecord record2 )
{
Objects.requireNonNull( record1 );
Objects.requireNonNull( record2 );

return record1.getId() == record2.getId() &&
record1.inUse() == record2.inUse() &&
record1.getNextProp() == record2.getNextProp() &&
record1.getNextRel() == record2.getNextRel() &&
record1.isDense() == record2.isDense() &&
record1.getLabelField() == record2.getLabelField();
}

@Override
public String name()
{
return "node";
}
}

0 comments on commit 569e4d4

Please sign in to comment.