Skip to content

Commit

Permalink
Remove introduced Fixed reference capability.
Browse files Browse the repository at this point in the history
Introduce format family and use it as one of the criteria for format migration.
Based on format family not it's possible to see what kind of format do we see - Standard, High limit or other based on its family that is the same across all versions.
  • Loading branch information
MishaDemianenko committed Aug 29, 2016
1 parent 81fdc24 commit dd62119
Show file tree
Hide file tree
Showing 21 changed files with 287 additions and 160 deletions.
Expand Up @@ -37,11 +37,6 @@ public enum Capability
*/
DENSE_NODES( CapabilityType.FORMAT, CapabilityType.STORE ),

/**
* Store has fixed reference encoding support
*/
FIXED_REFERENCE( CapabilityType.FORMAT ),

/**
* Store has version trailers in the end of cleanly shut down store
*/
Expand Down
@@ -0,0 +1,70 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.neo4j.kernel.impl.store.format;

/**
* Family of the format. Family of format is specific to a format across all version that format support.
* Two formats in different versions should have same format family.
* Family is one of the criteria that will determine if migration between formats is possible.
*/
public abstract class FormatFamily implements Comparable<FormatFamily>
{
/**
* Get format family name
* @return family name
*/
public abstract String getName();

/**
* get format family rank
* @return rank
*/
public abstract int rank();

@Override
public int compareTo( FormatFamily formatFamily )
{
return Integer.compare( this.rank(), formatFamily.rank() );
}

/**
* Check if migration between provided font families is possible.
* Family is upgradable if rank of the new family is higher then rank of old family
* @param oldFamily old family
* @param newFamily new family
* @return true if upgrade between families is possible, false otherwise
*/
public static boolean isUpgradable( FormatFamily oldFamily, FormatFamily newFamily )
{
return oldFamily.compareTo( newFamily ) < 0;
}

/**
* Check if provided font families is not upgradable.
* Family is not upgradable if rank of the new family is lower or equal to rank of old family
* @param oldFamily old family
* @param newFamily new family
* @return true if families not upgradable, false otherwise
*/
public static boolean isNotUpgradable( FormatFamily oldFamily, FormatFamily newFamily )
{
return oldFamily.compareTo( newFamily ) > 0;
}
}
Expand Up @@ -92,6 +92,8 @@ public Factory( String key, String... altKeys )
*/
boolean hasCapability( Capability capability );

FormatFamily getFormatFamily();

/**
* Whether or not this format has the same capabilities of the specific {@code type} as the {@code other} format.
*
Expand Down
Expand Up @@ -19,67 +19,29 @@
*/
package org.neo4j.kernel.impl.store.format;

import javax.annotation.Nonnull;

/**
* All known store formats are collected here.
*/
public enum StoreVersion
{
STANDARD_V2_0( "v0.A.1", true ),
STANDARD_V2_1( "v0.A.3", true ),
STANDARD_V2_2( "v0.A.5", true ),
STANDARD_V2_3( "v0.A.6", true ),
STANDARD_V3_0( "v0.A.7", true ),

HIGH_LIMIT_V3_0( "vE.H.0", false ),
HIGH_LIMIT_V3_1( "vE.H.1", false );
STANDARD_V2_0( "v0.A.1" ),
STANDARD_V2_1( "v0.A.3" ),
STANDARD_V2_2( "v0.A.5" ),
STANDARD_V2_3( "v0.A.6" ),
STANDARD_V3_0( "v0.A.7" ),

private static final StoreVersion[] ALL_STORE_VERSIONS = values();
HIGH_LIMIT_V3_0( "vE.H.0" ),
HIGH_LIMIT_V3_1( "vE.H.1" );

private final String versionString;
private final boolean isCommunity;

StoreVersion( String versionString, boolean isCommunity )
StoreVersion( String versionString )
{
this.versionString = versionString;
this.isCommunity = isCommunity;
}

public String versionString()
{
return versionString;
}

/**
* @param version string
* @return true if the store version is a known community format, false otherwise
*/
public static boolean isCommunityStoreVersion( @Nonnull String version )
{
for ( StoreVersion storeVersion : ALL_STORE_VERSIONS )
{
if ( storeVersion.versionString.equals( version ) && storeVersion.isCommunity )
{
return true;
}
}
return false;
}

/**
* @param version string
* @return true if the store version is a known enterprise format, false otherwise
*/
public static boolean isEnterpriseStoreVersion( @Nonnull String version )
{
for ( StoreVersion storeVersion : ALL_STORE_VERSIONS )
{
if ( storeVersion.versionString.equals( version ) && !storeVersion.isCommunity )
{
return true;
}
}
return false;
}
}
@@ -0,0 +1,48 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.neo4j.kernel.impl.store.format.standard;

import org.neo4j.kernel.impl.store.format.FormatFamily;

/**
* Standard format family.
* @see FormatFamily
*/
public class StandardFormatFamily extends FormatFamily
{
public static final FormatFamily INSTANCE = new StandardFormatFamily();

private StandardFormatFamily()
{
}

@Override
public String getName()
{
return "Standard format family";
}

@Override
public int rank()
{
return 0;
}

}
Expand Up @@ -21,6 +21,7 @@

import org.neo4j.kernel.impl.store.format.BaseRecordFormats;
import org.neo4j.kernel.impl.store.format.Capability;
import org.neo4j.kernel.impl.store.format.FormatFamily;
import org.neo4j.kernel.impl.store.format.RecordFormat;
import org.neo4j.kernel.impl.store.format.RecordFormats;
import org.neo4j.kernel.impl.store.format.StoreVersion;
Expand Down Expand Up @@ -90,4 +91,10 @@ public RecordFormat<DynamicRecord> dynamic()
{
return new DynamicRecordFormat();
}

@Override
public FormatFamily getFormatFamily()
{
return StandardFormatFamily.INSTANCE;
}
}
Expand Up @@ -21,6 +21,7 @@

import org.neo4j.kernel.impl.store.format.BaseRecordFormats;
import org.neo4j.kernel.impl.store.format.Capability;
import org.neo4j.kernel.impl.store.format.FormatFamily;
import org.neo4j.kernel.impl.store.format.RecordFormat;
import org.neo4j.kernel.impl.store.format.RecordFormats;
import org.neo4j.kernel.impl.store.format.StoreVersion;
Expand Down Expand Up @@ -91,4 +92,10 @@ public RecordFormat<DynamicRecord> dynamic()
{
return new DynamicRecordFormat();
}

@Override
public FormatFamily getFormatFamily()
{
return StandardFormatFamily.INSTANCE;
}
}
Expand Up @@ -21,6 +21,7 @@

import org.neo4j.kernel.impl.store.format.BaseRecordFormats;
import org.neo4j.kernel.impl.store.format.Capability;
import org.neo4j.kernel.impl.store.format.FormatFamily;
import org.neo4j.kernel.impl.store.format.RecordFormat;
import org.neo4j.kernel.impl.store.format.RecordFormats;
import org.neo4j.kernel.impl.store.format.StoreVersion;
Expand Down Expand Up @@ -91,4 +92,10 @@ public RecordFormat<DynamicRecord> dynamic()
{
return new DynamicRecordFormat();
}

@Override
public FormatFamily getFormatFamily()
{
return StandardFormatFamily.INSTANCE;
}
}
Expand Up @@ -21,6 +21,7 @@

import org.neo4j.kernel.impl.store.format.BaseRecordFormats;
import org.neo4j.kernel.impl.store.format.Capability;
import org.neo4j.kernel.impl.store.format.FormatFamily;
import org.neo4j.kernel.impl.store.format.RecordFormat;
import org.neo4j.kernel.impl.store.format.RecordFormats;
import org.neo4j.kernel.impl.store.format.StoreVersion;
Expand Down Expand Up @@ -90,4 +91,10 @@ public RecordFormat<DynamicRecord> dynamic()
{
return new DynamicRecordFormat();
}

@Override
public FormatFamily getFormatFamily()
{
return StandardFormatFamily.INSTANCE;
}
}
Expand Up @@ -21,6 +21,7 @@

import org.neo4j.kernel.impl.store.format.BaseRecordFormats;
import org.neo4j.kernel.impl.store.format.Capability;
import org.neo4j.kernel.impl.store.format.FormatFamily;
import org.neo4j.kernel.impl.store.format.RecordFormat;
import org.neo4j.kernel.impl.store.format.RecordFormats;
import org.neo4j.kernel.impl.store.format.StoreVersion;
Expand Down Expand Up @@ -91,4 +92,10 @@ public RecordFormat<DynamicRecord> dynamic()
{
return new DynamicRecordFormat();
}

@Override
public FormatFamily getFormatFamily()
{
return StandardFormatFamily.INSTANCE;
}
}
Expand Up @@ -25,9 +25,9 @@
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.kernel.impl.store.MetaDataStore;
import org.neo4j.kernel.impl.store.format.Capability;
import org.neo4j.kernel.impl.store.format.FormatFamily;
import org.neo4j.kernel.impl.store.format.RecordFormatSelector;
import org.neo4j.kernel.impl.store.format.RecordFormats;
import org.neo4j.kernel.impl.store.format.StoreVersion;
import org.neo4j.kernel.impl.storemigration.StoreUpgrader.DatabaseNotCleanlyShutDownException;
import org.neo4j.kernel.impl.storemigration.StoreUpgrader.UnexpectedUpgradingStoreFormatException;
import org.neo4j.kernel.impl.storemigration.StoreUpgrader.UnexpectedUpgradingStoreVersionException;
Expand Down Expand Up @@ -88,18 +88,18 @@ public RecordFormats checkUpgradeable( File storeDirectory )
return format;
}

// If we are trying to open an enterprise store when configured to use community format, then inform the user
// of the config setting to change since downgrades aren't possible but the store can still be opened.
if ( StoreVersion.isEnterpriseStoreVersion( result.actualVersion ) &&
StoreVersion.isCommunityStoreVersion( format.storeVersion() ) )
{
throw new StoreUpgrader.UnexpectedUpgradingStoreFormatException();
}

RecordFormats fromFormat;
try
{
fromFormat = RecordFormatSelector.selectForVersion( result.actualVersion );

// If we are trying to open an enterprise store when configured to use community format, then inform the user
// of the config setting to change since downgrades aren't possible but the store can still be opened.
if ( FormatFamily.isNotUpgradable( fromFormat.getFormatFamily(), format.getFormatFamily() ) )
{
throw new StoreUpgrader.UnexpectedUpgradingStoreFormatException();
}

if ( fromFormat.generation() > format.generation() )
{
// Tried to downgrade, that isn't supported
Expand Down
Expand Up @@ -56,6 +56,7 @@
import org.neo4j.kernel.impl.store.TransactionId;
import org.neo4j.kernel.impl.store.counts.CountsTracker;
import org.neo4j.kernel.impl.store.format.CapabilityType;
import org.neo4j.kernel.impl.store.format.FormatFamily;
import org.neo4j.kernel.impl.store.format.RecordFormats;
import org.neo4j.kernel.impl.store.format.standard.MetaDataRecordFormat;
import org.neo4j.kernel.impl.store.format.standard.NodeRecordFormat;
Expand Down Expand Up @@ -170,7 +171,7 @@ public void migrate( File storeDir, File migrationDir, MigrationProgressMonitor.

RecordFormats oldFormat = selectForVersion( versionToMigrateFrom );
RecordFormats newFormat = selectForVersion( versionToMigrateTo );
if ( !oldFormat.hasSameCapabilities( newFormat, CapabilityType.FORMAT ) )
if ( upgradeFormatType( oldFormat, newFormat ) || isDifferentCapabilities( oldFormat, newFormat ) )
{
// TODO if this store has relationship indexes then warn user about that they will be incorrect
// after migration, because now we're rewriting the relationship ids.
Expand All @@ -192,6 +193,16 @@ public void migrate( File storeDir, File migrationDir, MigrationProgressMonitor.
// must be a proper translation happening while doing so.
}

private boolean isDifferentCapabilities( RecordFormats oldFormat, RecordFormats newFormat )
{
return !oldFormat.hasSameCapabilities( newFormat, CapabilityType.FORMAT );
}

private boolean upgradeFormatType( RecordFormats oldFormat, RecordFormats newFormat )
{
return FormatFamily.isUpgradable( oldFormat.getFormatFamily(), newFormat.getFormatFamily() );
}

void writeLastTxInformation( File migrationDir, TransactionId txInfo ) throws IOException
{
writeTxLogCounters( fileSystem, lastTxInformationFile( migrationDir ),
Expand Down

0 comments on commit dd62119

Please sign in to comment.