diff --git a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java
index 6c0d18d449a3f..1df1e7b930032 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java
@@ -604,7 +604,7 @@ public long getTimestampForVersion( long version ) throws IOException
}
};
final LogFileInformation logFileInformation =
- new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore, logInformation );
+ new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore::getLastCommittedTransactionId, logInformation );
String pruningConf = config.get(
config.get( GraphDatabaseFacadeFactory.Configuration.ephemeral )
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/LogFileInformation.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/LogFileInformation.java
index 0dd6e852b5d45..e438354b5518d 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/LogFileInformation.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/LogFileInformation.java
@@ -24,25 +24,25 @@
public interface LogFileInformation
{
/**
- * @return the reachable transaction that is farthest back of them all, in any existing version.
+ * @return the reachable entry that is farthest back of them all, in any existing version.
*/
- long getFirstExistingTxId() throws IOException;
+ long getFirstExistingEntryId() throws IOException;
/**
* @param version the log version to get first committed tx for.
- * @return the first committed transaction id for the log with {@code version}.
+ * @return the first committed entry id for the log with {@code version}.
* If that log doesn't exist -1 is returned.
*/
- long getFirstCommittedTxId( long version ) throws IOException;
+ long getFirstEntryId( long version ) throws IOException;
/**
- * @return the last committed transaction id for this Log
+ * @return the last committed entry id for this Log
*/
- long getLastCommittedTxId();
+ long getLastEntryId();
/**
- * @param version the log version to get first tx timestamp for.
- * @return the timestamp for the start record for the first encountered transaction
+ * @param version the log version to get first entry timestamp for.
+ * @return the timestamp for the start record for the first encountered entry
* in the log {@code version}.
*/
long getFirstStartRecordTimestamp( long version ) throws IOException;
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/PhysicalLogFileInformation.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/PhysicalLogFileInformation.java
index 3460ea5383bac..6d3c1e26a148c 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/PhysicalLogFileInformation.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/PhysicalLogFileInformation.java
@@ -28,30 +28,36 @@ public interface LogVersionToTimestamp
long getTimestampForVersion( long version ) throws IOException;
}
+
+ public interface LastEntryInLog
+ {
+ long getLastEntryId( );
+ }
+
private final PhysicalLogFiles logFiles;
private final LogHeaderCache logHeaderCache;
- private final TransactionIdStore transactionIdStore;
+ private final LastEntryInLog lastEntryInLog;
private final LogVersionToTimestamp logVersionToTimestamp;
public PhysicalLogFileInformation( PhysicalLogFiles logFiles,
LogHeaderCache logHeaderCache,
- TransactionIdStore transactionIdStore,
+ LastEntryInLog lastEntryInLog,
LogVersionToTimestamp logVersionToTimestamp )
{
this.logFiles = logFiles;
this.logHeaderCache = logHeaderCache;
- this.transactionIdStore = transactionIdStore;
+ this.lastEntryInLog = lastEntryInLog;
this.logVersionToTimestamp = logVersionToTimestamp;
}
@Override
- public long getFirstExistingTxId() throws IOException
+ public long getFirstExistingEntryId() throws IOException
{
long version = logFiles.getHighestLogVersion();
long candidateFirstTx = -1;
while ( logFiles.versionExists( version ) )
{
- candidateFirstTx = getFirstCommittedTxId( version );
+ candidateFirstTx = getFirstEntryId( version );
version--;
}
version++; // the loop above goes back one version too far.
@@ -62,7 +68,7 @@ public long getFirstExistingTxId() throws IOException
}
@Override
- public long getFirstCommittedTxId( long version ) throws IOException
+ public long getFirstEntryId( long version ) throws IOException
{
long logHeader = logHeaderCache.getLogHeader( version );
if ( logHeader != -1 )
@@ -81,9 +87,9 @@ public long getFirstCommittedTxId( long version ) throws IOException
}
@Override
- public long getLastCommittedTxId()
+ public long getLastEntryId()
{
- return transactionIdStore.getLastCommittedTransactionId();
+ return lastEntryInLog.getLastEntryId();
}
@Override
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionCountThreshold.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryCountThreshold.java
similarity index 89%
rename from community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionCountThreshold.java
rename to community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryCountThreshold.java
index 822ca18dcdd30..8e4fac48ca611 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionCountThreshold.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryCountThreshold.java
@@ -25,11 +25,11 @@
import org.neo4j.kernel.impl.transaction.log.IllegalLogFormatException;
import org.neo4j.kernel.impl.transaction.log.LogFileInformation;
-public final class TransactionCountThreshold implements Threshold
+public final class EntryCountThreshold implements Threshold
{
private final long maxTransactionCount;
- TransactionCountThreshold( long maxTransactionCount )
+ EntryCountThreshold( long maxTransactionCount )
{
this.maxTransactionCount = maxTransactionCount;
}
@@ -46,7 +46,7 @@ public boolean reached( File ignored, long version, LogFileInformation source )
try
{
// try to ask next version log file which is my last tx
- long lastTx = source.getFirstCommittedTxId( version + 1 );
+ long lastTx = source.getFirstEntryId( version + 1 );
if ( lastTx == -1 )
{
throw new IllegalStateException(
@@ -54,7 +54,7 @@ public boolean reached( File ignored, long version, LogFileInformation source )
"PruneStrategy never checks the current active log file" );
}
- long highest = source.getLastCommittedTxId();
+ long highest = source.getLastEntryId();
return highest - lastTx >= maxTransactionCount;
}
catch ( IllegalLogFormatException e )
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionTimespanThreshold.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryTimespanThreshold.java
similarity index 92%
rename from community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionTimespanThreshold.java
rename to community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryTimespanThreshold.java
index 6e825dfa5f544..7814a22aceedd 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionTimespanThreshold.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryTimespanThreshold.java
@@ -27,14 +27,14 @@
import org.neo4j.kernel.impl.transaction.log.IllegalLogFormatException;
import org.neo4j.kernel.impl.transaction.log.LogFileInformation;
-public final class TransactionTimespanThreshold implements Threshold
+public final class EntryTimespanThreshold implements Threshold
{
private final long timeToKeepInMillis;
private final Clock clock;
private long lowerLimit;
- TransactionTimespanThreshold( Clock clock, TimeUnit timeUnit, long timeToKeep )
+ EntryTimespanThreshold( Clock clock, TimeUnit timeUnit, long timeToKeep )
{
this.clock = clock;
this.timeToKeepInMillis = timeUnit.toMillis( timeToKeep );
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruneStrategyFactory.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruneStrategyFactory.java
index c9586031224e7..e14e22cb5b8f1 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruneStrategyFactory.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruneStrategyFactory.java
@@ -92,7 +92,7 @@ public static LogPruneStrategy fromConfigValue( FileSystemAbstraction fileSystem
case "true":
return NO_PRUNING;
case "false":
- final TransactionCountThreshold thresholdToUse = new TransactionCountThreshold( 1 );
+ final EntryCountThreshold thresholdToUse = new EntryCountThreshold( 1 );
return new ThresholdBasedPruneStrategy( fileSystem, logFileInformation, files, thresholdToUse );
default:
throw new IllegalArgumentException( "Invalid log pruning configuration value '" + configValue +
@@ -121,17 +121,18 @@ static Threshold getThresholdByType( FileSystemAbstraction fileSystem, String ty
thresholdToUse = new FileSizeThreshold( fileSystem, thresholdValue );
break;
case "txs":
- thresholdToUse = new TransactionCountThreshold( thresholdValue );
+ case "entries": // txs and entries are synonyms
+ thresholdToUse = new EntryCountThreshold( thresholdValue );
break;
case "hours":
- thresholdToUse = new TransactionTimespanThreshold( Clock.SYSTEM_CLOCK, TimeUnit.HOURS, thresholdValue );
+ thresholdToUse = new EntryTimespanThreshold( Clock.SYSTEM_CLOCK, TimeUnit.HOURS, thresholdValue );
break;
case "days":
- thresholdToUse = new TransactionTimespanThreshold( Clock.SYSTEM_CLOCK, TimeUnit.DAYS, thresholdValue );
+ thresholdToUse = new EntryTimespanThreshold( Clock.SYSTEM_CLOCK, TimeUnit.DAYS, thresholdValue );
break;
default:
throw new IllegalArgumentException( "Invalid log pruning configuration value '" + originalConfigValue +
- "'. Invalid type '" + type + "', valid are files, size, txs, hours, days." );
+ "'. Invalid type '" + type + "', valid are files, size, txs, entries, hours, days." );
}
return thresholdToUse;
}
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/rotation/LogRotation.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/rotation/LogRotation.java
index dd78c27042624..3e20f91cfc318 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/rotation/LogRotation.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/rotation/LogRotation.java
@@ -53,6 +53,7 @@ public void rotateLogFile() throws IOException
};
/**
+ * Rotates the undelying log if it is required. Returns true if rotation happened, false otherwise
* @param logAppendEvent A trace event for the current log append operation.
*/
boolean rotateLogIfNeeded( LogAppendEvent logAppendEvent ) throws IOException;
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/PhysicalLogFileInformationTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/PhysicalLogFileInformationTest.java
index 3bc07c6ce0103..971dd4c992feb 100644
--- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/PhysicalLogFileInformationTest.java
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/PhysicalLogFileInformationTest.java
@@ -45,7 +45,7 @@ public class PhysicalLogFileInformationTest
@Test
public void shouldReadAndCacheFirstCommittedTransactionIdForAGivenVersionWhenNotCached() throws Exception
{
- PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore,
+ PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore::getLastCommittedTransactionId,
logVersionToTimestamp );
long expected = 5;
@@ -56,7 +56,7 @@ public void shouldReadAndCacheFirstCommittedTransactionIdForAGivenVersionWhenNot
new LogHeader( (byte) -1/*ignored*/, -1L/*ignored*/, expected - 1L )
);
- long firstCommittedTxId = info.getFirstCommittedTxId( version );
+ long firstCommittedTxId = info.getFirstEntryId( version );
assertEquals( expected, firstCommittedTxId );
verify( logHeaderCache, times( 1 ) ).putHeader( version, expected - 1 );
}
@@ -64,21 +64,21 @@ public void shouldReadAndCacheFirstCommittedTransactionIdForAGivenVersionWhenNot
@Test
public void shouldReadFirstCommittedTransactionIdForAGivenVersionWhenCached() throws Exception
{
- PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore,
+ PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore::getLastCommittedTransactionId,
logVersionToTimestamp );
long expected = 5;
long version = 10L;
when( logHeaderCache.getLogHeader( version ) ).thenReturn( expected - 1 );
- long firstCommittedTxId = info.getFirstCommittedTxId( version );
+ long firstCommittedTxId = info.getFirstEntryId( version );
assertEquals( expected, firstCommittedTxId );
}
@Test
public void shouldReadAndCacheFirstCommittedTransactionIdWhenNotCached() throws Exception
{
- PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore,
+ PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore::getLastCommittedTransactionId,
logVersionToTimestamp );
long expected = 5;
@@ -91,7 +91,7 @@ public void shouldReadAndCacheFirstCommittedTransactionIdWhenNotCached() throws
);
when( logFiles.hasAnyEntries( version ) ).thenReturn( true );
- long firstCommittedTxId = info.getFirstExistingTxId();
+ long firstCommittedTxId = info.getFirstExistingEntryId();
assertEquals( expected, firstCommittedTxId );
verify( logHeaderCache, times( 1 ) ).putHeader( version, expected - 1 );
}
@@ -99,7 +99,7 @@ public void shouldReadAndCacheFirstCommittedTransactionIdWhenNotCached() throws
@Test
public void shouldReadFirstCommittedTransactionIdWhenCached() throws Exception
{
- PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore,
+ PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore::getLastCommittedTransactionId,
logVersionToTimestamp );
long expected = 5;
@@ -109,21 +109,21 @@ public void shouldReadFirstCommittedTransactionIdWhenCached() throws Exception
when( logHeaderCache.getLogHeader( version ) ).thenReturn( expected -1 );
when( logFiles.hasAnyEntries( version ) ).thenReturn( true );
- long firstCommittedTxId = info.getFirstExistingTxId();
+ long firstCommittedTxId = info.getFirstExistingEntryId();
assertEquals( expected, firstCommittedTxId );
}
@Test
public void shouldReturnNothingWhenThereAreNoTransactions() throws Exception
{
- PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore,
+ PhysicalLogFileInformation info = new PhysicalLogFileInformation( logFiles, logHeaderCache, transactionIdStore::getLastCommittedTransactionId,
logVersionToTimestamp );
long version = 10L;
when( logFiles.getHighestLogVersion() ).thenReturn( version );
when( logFiles.hasAnyEntries( version ) ).thenReturn( false );
- long firstCommittedTxId = info.getFirstExistingTxId();
+ long firstCommittedTxId = info.getFirstExistingEntryId();
assertEquals( -1, firstCommittedTxId );
}
}
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/ReadTransactionLogWritingTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/ReadTransactionLogWritingTest.java
index 44a260950815f..c6a6f030e2c27 100644
--- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/ReadTransactionLogWritingTest.java
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/ReadTransactionLogWritingTest.java
@@ -102,7 +102,7 @@ private long countLogEntries()
filterNeostoreLogicalLog( fs, storeDir.getPath(), logicalLogCounter );
long txLogRecordCount = db.getDependencyResolver()
- .resolveDependency( LogFileInformation.class ).getLastCommittedTxId();
+ .resolveDependency( LogFileInformation.class ).getLastEntryId();
return logicalLogCounter.getCount() + txLogRecordCount;
}
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryCountThresholdTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryCountThresholdTest.java
new file mode 100644
index 0000000000000..80634664e86d7
--- /dev/null
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryCountThresholdTest.java
@@ -0,0 +1,217 @@
+/*
+ * 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.transaction.log.pruning;
+
+import org.junit.Test;
+
+import java.io.File;
+
+import org.neo4j.kernel.impl.transaction.log.IllegalLogFormatException;
+import org.neo4j.kernel.impl.transaction.log.LogFileInformation;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class EntryCountThresholdTest
+{
+ private LogFileInformation info = mock( LogFileInformation.class );
+ private File file = mock( File.class );
+
+ @Test
+ public void shouldReportThresholdReachedWhenThresholdIsReached() throws Exception
+ {
+ long version = 10L;
+
+ when( info.getFirstEntryId( version + 1 ) ).thenReturn( 1L );
+ when( info.getLastEntryId() ).thenReturn( 2L );
+
+ EntryCountThreshold threshold = new EntryCountThreshold( 1 );
+ boolean reached = threshold.reached( file, version, info );
+
+ assertTrue( reached );
+ }
+
+ @Test
+ public void shouldReportThresholdNotReachedWhenThresholdIsNotReached() throws Exception
+ {
+ long version = 10L;
+
+ when( info.getFirstEntryId( version ) ).thenReturn( 1L );
+ when( info.getFirstEntryId( version + 1 ) ).thenReturn( 1L );
+
+ when( info.getLastEntryId() ).thenReturn( 1L );
+
+ EntryCountThreshold threshold = new EntryCountThreshold( 1 );
+
+ assertFalse( threshold.reached( file, version, info ) );
+ }
+
+ @Test
+ public void shouldProperlyHandleCaseWithOneEntryPerLogFile() throws Exception
+ {
+ // Given 2 files with one entry each
+ when( info.getFirstEntryId( 1L ) ).thenReturn( 1L );
+ when( info.getFirstEntryId( 2L ) ).thenReturn( 2L );
+ when( info.getFirstEntryId( 3L ) ).thenReturn( 3L );
+
+ when( info.getLastEntryId() ).thenReturn( 3L );
+
+ // When the threshold is 1 entries
+ EntryCountThreshold threshold = new EntryCountThreshold( 1 );
+
+ // Then the last file should be kept around
+ assertFalse( threshold.reached( file, 2L, info ) );
+ assertTrue( threshold.reached( file, 1L, info ) );
+ }
+
+ @Test
+ public void shouldReturnTrueWhenLogFormatVersionIsOlderThanTheRequiredOne() throws Exception
+ {
+ long version = 10L;
+
+ when( info.getFirstEntryId( version + 1 ) ).thenThrow( new IllegalLogFormatException( 9L, 8L ) );
+
+ EntryCountThreshold threshold = new EntryCountThreshold( 2 );
+ boolean reached = threshold.reached( file, version, info );
+
+ assertTrue( reached );
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenLogFormatVersionIsNewerThanTheRequiredOne() throws Exception
+ {
+ long version = 10L;
+
+ when( info.getFirstEntryId( version + 1 ) ).thenThrow( new IllegalLogFormatException( 9L, 11L ) );
+
+ EntryCountThreshold threshold = new EntryCountThreshold( 2 );
+ try
+ {
+ threshold.reached( file, version, info );
+ fail( "should have thrown IllegalLogFormatException" );
+ }
+ catch ( RuntimeException e )
+ {
+ assertTrue( e.getCause() instanceof IllegalLogFormatException );
+ assertTrue( ((IllegalLogFormatException) e.getCause()).wasNewerLogVersion() );
+ }
+ }
+
+ @Test
+ public void shouldWorkWhenCalledMultipleTimesKeeping2Files() throws Exception
+ {
+ when( info.getFirstEntryId( 1L ) ).thenReturn( 1L );
+ when( info.getFirstEntryId( 2L ) ).thenReturn( 5L );
+ when( info.getFirstEntryId( 3L ) ).thenReturn( 15L );
+ when( info.getFirstEntryId( 4L ) ).thenReturn( 18L );
+ when( info.getLastEntryId() ).thenReturn( 18L );
+
+ EntryCountThreshold threshold = new EntryCountThreshold( 8 );
+
+ assertTrue( threshold.reached( file, 1L, info ) );
+
+ assertFalse( threshold.reached( file, 2L, info ) );
+
+ assertFalse( threshold.reached( file, 3L, info ) );
+ }
+
+ @Test
+ public void shouldWorkWhenCalledMultipleTimesKeeping3Files() throws Exception
+ {
+ when( info.getFirstEntryId( 1L ) ).thenReturn( 1L );
+ when( info.getFirstEntryId( 2L ) ).thenReturn( 5L );
+ when( info.getFirstEntryId( 3L ) ).thenReturn( 15L );
+ when( info.getFirstEntryId( 4L ) ).thenReturn( 18L );
+ when( info.getLastEntryId() ).thenReturn( 18L );
+
+ EntryCountThreshold threshold = new EntryCountThreshold( 15 );
+
+ assertFalse( threshold.reached( file, 1L, info ) );
+
+ assertFalse( threshold.reached( file, 2L, info ) );
+
+ assertFalse( threshold.reached( file, 3L, info ) );
+ }
+
+ @Test
+ public void shouldWorkWhenCalledMultipleTimesKeeping1FileOnBoundary() throws Exception
+ {
+ when( info.getFirstEntryId( 1L ) ).thenReturn( 1L );
+ when( info.getFirstEntryId( 2L ) ).thenReturn( 5L );
+ when( info.getFirstEntryId( 3L ) ).thenReturn( 15L );
+ when( info.getFirstEntryId( 4L ) ).thenReturn( 18L );
+ when( info.getLastEntryId() ).thenReturn( 18L );
+
+ EntryCountThreshold threshold = new EntryCountThreshold( 3 );
+
+ assertTrue( threshold.reached( file, 1L, info ) );
+ assertTrue( threshold.reached( file, 2L, info ) );
+ assertFalse( threshold.reached( file, 3L, info ) );
+ }
+
+ @Test
+ public void shouldSkipEmptyLogsBetweenLogsThatWillBeKept() throws Exception
+ {
+ // Given
+ // 1, 3 and 4 are empty. 2 has 5 transactions, 5 has 8, 6 is the current version
+ when( info.getFirstEntryId( 1L ) ).thenReturn( 1L );
+ when( info.getFirstEntryId( 2L ) ).thenReturn( 1L );
+ when( info.getFirstEntryId( 3L ) ).thenReturn( 5L );
+ when( info.getFirstEntryId( 4L ) ).thenReturn( 5L );
+ when( info.getFirstEntryId( 5L ) ).thenReturn( 5L );
+ when( info.getFirstEntryId( 6L ) ).thenReturn( 13L );
+ when( info.getLastEntryId() ).thenReturn( 13L );
+
+ // The threshold is 9, which is one more than what version 5 has, which means 2 should be kept
+ EntryCountThreshold threshold = new EntryCountThreshold( 9 );
+
+ assertFalse( threshold.reached( file, 5L, info ) );
+ assertFalse( threshold.reached( file, 4L, info ) );
+ assertFalse( threshold.reached( file, 3L, info ) );
+ assertFalse( threshold.reached( file, 2L, info ) );
+ assertTrue( threshold.reached( file, 1L, info ) );
+ }
+
+ @Test
+ public void shouldDeleteNonEmptyLogThatIsAfterASeriesOfEmptyLogs() throws Exception
+ {
+ // Given
+ // 1, 3 and 4 are empty. 2 has 5 transactions, 5 has 8, 6 is the current version
+ when( info.getFirstEntryId( 1L ) ).thenReturn( 1L );
+ when( info.getFirstEntryId( 2L ) ).thenReturn( 1L );
+ when( info.getFirstEntryId( 3L ) ).thenReturn( 5L );
+ when( info.getFirstEntryId( 4L ) ).thenReturn( 5L );
+ when( info.getFirstEntryId( 5L ) ).thenReturn( 5L );
+ when( info.getFirstEntryId( 6L ) ).thenReturn( 13L );
+ when( info.getLastEntryId() ).thenReturn( 13L );
+
+ // The threshold is 8, which is exactly what version 5 has, which means 2 should be deleted
+ EntryCountThreshold threshold = new EntryCountThreshold( 8 );
+
+ assertFalse( threshold.reached( file, 5L, info ) );
+ assertTrue( threshold.reached( file, 4L, info ) );
+ assertTrue( threshold.reached( file, 3L, info ) );
+ assertTrue( threshold.reached( file, 2L, info ) );
+ assertTrue( threshold.reached( file, 1L, info ) );
+ }
+}
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionTimespanThresholdTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryTimespanThresholdTest.java
similarity index 84%
rename from community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionTimespanThresholdTest.java
rename to community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryTimespanThresholdTest.java
index f2e1d5c071788..42c251d595b29 100644
--- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionTimespanThresholdTest.java
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/EntryTimespanThresholdTest.java
@@ -36,7 +36,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-public class TransactionTimespanThresholdTest
+public class EntryTimespanThresholdTest
{
private final File file = mock( File.class );
private final LogFileInformation source = mock( LogFileInformation.class );
@@ -47,8 +47,8 @@ public void shouldReturnFalseWhenTimeIsEqualOrAfterTheLowerLimit() throws IOExce
{
// given
FrozenClock clock = new FrozenClock( 1000l, TimeUnit.MILLISECONDS );
- final TransactionTimespanThreshold threshold =
- new TransactionTimespanThreshold( clock, TimeUnit.MILLISECONDS, 200 );
+ final EntryTimespanThreshold threshold =
+ new EntryTimespanThreshold( clock, TimeUnit.MILLISECONDS, 200 );
when( source.getFirstStartRecordTimestamp( version ) ).thenReturn( 800l );
@@ -65,8 +65,8 @@ public void shouldReturnReturnWhenTimeIsBeforeTheLowerLimit() throws IOException
{
// given
FrozenClock clock = new FrozenClock( 1000l, TimeUnit.MILLISECONDS );
- final TransactionTimespanThreshold threshold =
- new TransactionTimespanThreshold( clock, TimeUnit.MILLISECONDS, 100 );
+ final EntryTimespanThreshold threshold =
+ new EntryTimespanThreshold( clock, TimeUnit.MILLISECONDS, 100 );
when( source.getFirstStartRecordTimestamp( version ) ).thenReturn( 800l );
@@ -83,8 +83,8 @@ public void shouldReturnTrueIfTheLogHasAnOlderVersion() throws IOException
{
// given
FrozenClock clock = new FrozenClock( 1000l, TimeUnit.MILLISECONDS );
- final TransactionTimespanThreshold threshold =
- new TransactionTimespanThreshold( clock, TimeUnit.MILLISECONDS, 100 );
+ final EntryTimespanThreshold threshold =
+ new EntryTimespanThreshold( clock, TimeUnit.MILLISECONDS, 100 );
when( source.getFirstStartRecordTimestamp( version ) ).thenThrow( new IllegalLogFormatException( version, 3 ) );
@@ -101,8 +101,8 @@ public void shouldThrowIfTheLogHasANewerVersion() throws IOException
{
// given
FrozenClock clock = new FrozenClock( 1000l, TimeUnit.MILLISECONDS );
- final TransactionTimespanThreshold threshold =
- new TransactionTimespanThreshold( clock, TimeUnit.MILLISECONDS, 100 );
+ final EntryTimespanThreshold threshold =
+ new EntryTimespanThreshold( clock, TimeUnit.MILLISECONDS, 100 );
final IllegalLogFormatException ex = new IllegalLogFormatException( version, 5 );
when( source.getFirstStartRecordTimestamp( version ) ).thenThrow( ex );
@@ -123,8 +123,8 @@ public void shouldThrowIfTheLogCannotBeRead() throws IOException
{
// given
FrozenClock clock = new FrozenClock( 1000l, TimeUnit.MILLISECONDS );
- final TransactionTimespanThreshold threshold =
- new TransactionTimespanThreshold( clock, TimeUnit.MILLISECONDS, 100 );
+ final EntryTimespanThreshold threshold =
+ new EntryTimespanThreshold( clock, TimeUnit.MILLISECONDS, 100 );
final IOException ex = new IOException( );
when( source.getFirstStartRecordTimestamp( version ) ).thenThrow( ex );
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruneStrategyFactoryTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruneStrategyFactoryTest.java
index 8bb72669d412f..7b77d2af5f33c 100644
--- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruneStrategyFactoryTest.java
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruneStrategyFactoryTest.java
@@ -29,16 +29,16 @@
public class LogPruneStrategyFactoryTest
{
-
@Test
public void testLogPruneThresholdsByType() throws Exception
{
assertThat( getPruneStrategy( "files", "25", "25 files" ), instanceOf( FileCountThreshold.class ) );
assertThat( getPruneStrategy( "size", "16G", "16G size" ), instanceOf( FileSizeThreshold.class ) );
- assertThat( getPruneStrategy( "txs", "4G", "4G txs" ), instanceOf( TransactionCountThreshold.class ) );
- assertThat( getPruneStrategy( "hours", "100", "100 hours" ), instanceOf( TransactionTimespanThreshold.class ) );
+ assertThat( getPruneStrategy( "txs", "4G", "4G txs" ), instanceOf( EntryCountThreshold.class ) );
+ assertThat( getPruneStrategy( "entries", "4G", "4G entries" ), instanceOf( EntryCountThreshold.class ) );
+ assertThat( getPruneStrategy( "hours", "100", "100 hours" ), instanceOf( EntryTimespanThreshold.class ) );
assertThat( getPruneStrategy( "days", "100k", "100k days" ),
- instanceOf( TransactionTimespanThreshold.class) );
+ instanceOf( EntryTimespanThreshold.class) );
}
private Threshold getPruneStrategy(String type, String value, String configValue)
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionCountThresholdTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionCountThresholdTest.java
deleted file mode 100644
index fbaccad90635e..0000000000000
--- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/pruning/TransactionCountThresholdTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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.transaction.log.pruning;
-
-import org.junit.Test;
-
-import java.io.File;
-
-import org.neo4j.kernel.impl.transaction.log.IllegalLogFormatException;
-import org.neo4j.kernel.impl.transaction.log.LogFileInformation;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class TransactionCountThresholdTest
-{
- private LogFileInformation info = mock( LogFileInformation.class );
- private File file = mock( File.class );
-
- @Test
- public void shouldReportThresholdReachedWhenThresholdIsReached() throws Exception
- {
- long version = 10l;
-
- when( info.getFirstCommittedTxId( version + 1 ) ).thenReturn( 1l );
- when( info.getLastCommittedTxId() ).thenReturn( 2l );
-
- TransactionCountThreshold threshold = new TransactionCountThreshold( 1 );
- boolean reached = threshold.reached( file, version, info );
-
- assertTrue( reached );
- }
-
- @Test
- public void shouldReportThresholdNotReachedWhenThresholdIsNotReached() throws Exception
- {
- long version = 10l;
-
- when( info.getFirstCommittedTxId( version + 1 ) ).thenReturn( 1l );
- when( info.getLastCommittedTxId() ).thenReturn( 2l );
-
- TransactionCountThreshold threshold = new TransactionCountThreshold( 2 );
- boolean reached = threshold.reached( file, version, info );
-
- assertFalse( reached );
- }
-
- @Test
- public void shouldReturnTrueWhenLogFormatVersionIsOlderThanTheRequiredOne() throws Exception
- {
- long version = 10l;
-
- when( info.getFirstCommittedTxId( version + 1 ) ).thenThrow( new IllegalLogFormatException( 9l, 8l ) );
-
- TransactionCountThreshold threshold = new TransactionCountThreshold( 2 );
- boolean reached = threshold.reached( file, version, info );
-
- assertTrue( reached );
- }
-
- @Test
- public void shouldThrowExceptionWhenLogFormatVersionIsNewerThanTheRequiredOne() throws Exception
- {
- long version = 10l;
-
- when( info.getFirstCommittedTxId( version + 1 ) ).thenThrow( new IllegalLogFormatException( 9l, 11l ) );
-
- TransactionCountThreshold threshold = new TransactionCountThreshold( 2 );
- try
- {
- threshold.reached( file, version, info );
- fail( "should have thrown IllegalLogFormatException" );
- }
- catch ( RuntimeException e )
- {
- assertTrue( e.getCause() instanceof IllegalLogFormatException );
- assertTrue( ((IllegalLogFormatException) e.getCause()).wasNewerLogVersion() );
- }
- }
-
- @Test
- public void shouldWorkWhenCalledMultipleTimesKeeping2Files() throws Exception
- {
- when( info.getFirstCommittedTxId( 1l ) ).thenReturn( 1l );
- when( info.getFirstCommittedTxId( 2l ) ).thenReturn( 5l );
- when( info.getFirstCommittedTxId( 3l ) ).thenReturn( 15l );
- when( info.getFirstCommittedTxId( 4l ) ).thenReturn( 18l );
- when( info.getLastCommittedTxId() ).thenReturn( 18l );
-
- TransactionCountThreshold threshold = new TransactionCountThreshold( 8 );
-
- assertTrue( threshold.reached( file, 1l, info ) );
-
- assertFalse( threshold.reached( file, 2l, info ) );
-
- assertFalse( threshold.reached( file, 3l, info ) );
- }
-
- @Test
- public void shouldWorkWhenCalledMultipleTimesKeeping3Files() throws Exception
- {
- when( info.getFirstCommittedTxId( 1l ) ).thenReturn( 1l );
- when( info.getFirstCommittedTxId( 2l ) ).thenReturn( 5l );
- when( info.getFirstCommittedTxId( 3l ) ).thenReturn( 15l );
- when( info.getFirstCommittedTxId( 4l ) ).thenReturn( 18l );
- when( info.getLastCommittedTxId() ).thenReturn( 18l );
-
- TransactionCountThreshold threshold = new TransactionCountThreshold( 15 );
-
- assertFalse( threshold.reached( file, 1l, info ) );
-
- assertFalse( threshold.reached( file, 2l, info ) );
-
- assertFalse( threshold.reached( file, 3l, info ) );
- }
-
- @Test
- public void shouldWorkWhenCalledMultipleTimesKeeping1FileOnBoundary() throws Exception
- {
- when( info.getFirstCommittedTxId( 1l ) ).thenReturn( 1l );
- when( info.getFirstCommittedTxId( 2l ) ).thenReturn( 5l );
- when( info.getFirstCommittedTxId( 3l ) ).thenReturn( 15l );
- when( info.getFirstCommittedTxId( 4l ) ).thenReturn( 18l );
- when( info.getLastCommittedTxId() ).thenReturn( 18l );
-
- TransactionCountThreshold threshold = new TransactionCountThreshold( 3 );
-
- assertTrue( threshold.reached( file, 1l, info ) );
-
- assertTrue( threshold.reached( file, 2l, info ) );
-
- assertFalse( threshold.reached( file, 3l, info ) );
- }
-
- @Test
- public void shouldSkipEmptyLogsBetweenLogsThatWillBeKept() throws Exception
- {
- // Given
- // 1, 3 and 4 are empty. 2 has 5 transactions, 5 has 8, 6 is the current version
- when( info.getFirstCommittedTxId( 1l ) ).thenReturn( 1l );
- when( info.getFirstCommittedTxId( 2l ) ).thenReturn( 1l );
- when( info.getFirstCommittedTxId( 3l ) ).thenReturn( 5l );
- when( info.getFirstCommittedTxId( 4l ) ).thenReturn( 5l );
- when( info.getFirstCommittedTxId( 5l ) ).thenReturn( 5l );
- when( info.getFirstCommittedTxId( 6l ) ).thenReturn( 13l );
- when( info.getLastCommittedTxId() ).thenReturn( 13l );
-
- // The threshold is 9, which is one more than what version 5 has, which means 2 should be kept
- TransactionCountThreshold threshold = new TransactionCountThreshold( 9 );
-
- assertFalse( threshold.reached( file, 5l, info ) );
- assertFalse( threshold.reached( file, 4l, info ) );
- assertFalse( threshold.reached( file, 3l, info ) );
- assertFalse( threshold.reached( file, 2l, info ) );
- assertTrue( threshold.reached( file, 1l, info ) );
- }
-
- @Test
- public void shouldDeleteNonEmptyLogThatIsAfterASeriesOfEmptyLogs() throws Exception
- {
- // Given
- // 1, 3 and 4 are empty. 2 has 5 transactions, 5 has 8, 6 is the current version
- when( info.getFirstCommittedTxId( 1l ) ).thenReturn( 1l );
- when( info.getFirstCommittedTxId( 2l ) ).thenReturn( 1l );
- when( info.getFirstCommittedTxId( 3l ) ).thenReturn( 5l );
- when( info.getFirstCommittedTxId( 4l ) ).thenReturn( 5l );
- when( info.getFirstCommittedTxId( 5l ) ).thenReturn( 5l );
- when( info.getFirstCommittedTxId( 6l ) ).thenReturn( 13l );
- when( info.getLastCommittedTxId() ).thenReturn( 13l );
-
- // The threshold is 8, which is exactly what version 5 has, which means 2 should be deleted
- TransactionCountThreshold threshold = new TransactionCountThreshold( 8 );
-
- assertFalse( threshold.reached( file, 5l, info ) );
- assertTrue( threshold.reached( file, 4l, info ) );
- assertTrue( threshold.reached( file, 3l, info ) );
- assertTrue( threshold.reached( file, 2l, info ) );
- assertTrue( threshold.reached( file, 1l, info ) );
- }
-}
diff --git a/enterprise/backup/src/main/java/org/neo4j/backup/StoreCopyResponsePacker.java b/enterprise/backup/src/main/java/org/neo4j/backup/StoreCopyResponsePacker.java
index 2f1e80301c2ac..fbdf75d8aab1f 100644
--- a/enterprise/backup/src/main/java/org/neo4j/backup/StoreCopyResponsePacker.java
+++ b/enterprise/backup/src/main/java/org/neo4j/backup/StoreCopyResponsePacker.java
@@ -96,7 +96,7 @@ protected void extractTransactions( long startingAtTransactionId,
{
// We don't necessarily need to ask that far back. Ask which is the oldest transaction in the log(s)
// that we can possibly serve
- long oldestExistingTransactionId = logFileInformation.getFirstExistingTxId();
+ long oldestExistingTransactionId = logFileInformation.getFirstExistingEntryId();
if ( oldestExistingTransactionId == -1 )
{
// Seriously, there are no logs that we can serve?