Skip to content

Commit

Permalink
Fixed command aggregation for legacy indexes
Browse files Browse the repository at this point in the history
LegacyIndexTransactionStateImpl is responsible for tracking node/relationship
additions and removals. It uses two separate maps for this. Each map has index
name as a key and list of corresponding commands as a value. When index is
dropped, corresponding list of commands is cleared.

However additions to relationship legacy index ended up in the map dedicated
to node legacy index and removals from relationship legacy index cleared
commands from the node map. In particular this was a problem for node and
relationship indexes that had same name. It could lead to missing entries in the
legacy index after transaction completed successfully.

This commit makes LegacyIndexTransactionStateImpl use relationship map for
relationship commands.
It also improves equals/hashCode methods for legacy index commands.
  • Loading branch information
lutovich committed Dec 3, 2015
1 parent 96776ba commit 035526d
Show file tree
Hide file tree
Showing 5 changed files with 463 additions and 40 deletions.
Expand Up @@ -162,10 +162,10 @@ private void addCommand( String indexName, IndexCommand command, boolean clearFi
} }
else if ( command.getEntityType() == IndexEntityType.Relationship.id() ) else if ( command.getEntityType() == IndexEntityType.Relationship.id() )
{ {
commands = nodeCommands.get( indexName ); commands = relationshipCommands.get( indexName );
if ( commands == null ) if ( commands == null )
{ {
nodeCommands.put( indexName, commands = new ArrayList<>() ); relationshipCommands.put( indexName, commands = new ArrayList<>() );
} }
} }
else else
Expand Down
Expand Up @@ -21,6 +21,7 @@


import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Objects;


import org.neo4j.graphdb.index.Index; import org.neo4j.graphdb.index.Index;
import org.neo4j.kernel.impl.transaction.command.Command; import org.neo4j.kernel.impl.transaction.command.Command;
Expand Down Expand Up @@ -205,22 +206,28 @@ public byte endNodeNeedsLong()
} }


@Override @Override
public int hashCode() public boolean equals( Object o )
{ {
int result = (int) (startNode ^ (startNode >>> 32)); if ( this == o )
result = 31 * result + (int) (endNode ^ (endNode >>> 32)); {
return result; return true;
}
if ( o == null || getClass() != o.getClass() )
{
return false;
}
if ( !super.equals( o ) )
{
return false;
}
AddRelationshipCommand that = (AddRelationshipCommand) o;
return startNode == that.startNode && endNode == that.endNode;
} }


@Override @Override
public boolean equals( Object obj ) public int hashCode()
{ {
if ( !super.equals( obj ) ) return Objects.hash( super.hashCode(), startNode, endNode );
{
return false;
}
AddRelationshipCommand other = (AddRelationshipCommand) obj;
return startNode == other.startNode && endNode == other.endNode;
} }


@Override @Override
Expand Down Expand Up @@ -297,15 +304,28 @@ public Map<String, String> getConfig()
} }


@Override @Override
public int hashCode() public boolean equals( Object o )
{ {
return config != null ? config.hashCode() : 0; if ( this == o )
{
return true;
}
if ( o == null || getClass() != o.getClass() )
{
return false;
}
if ( !super.equals( o ) )
{
return false;
}
CreateCommand that = (CreateCommand) o;
return Objects.equals( config, that.config );
} }


@Override @Override
public boolean equals( Object obj ) public int hashCode()
{ {
return super.equals( obj ) && config.equals( ((CreateCommand)obj).config ); return Objects.hash( super.hashCode(), config );
} }


@Override @Override
Expand All @@ -323,20 +343,34 @@ public String toString()
} }


@Override @Override
public boolean equals( Object obj ) public boolean equals( Object o )
{ {
IndexCommand other = (IndexCommand) obj; if ( this == o )
boolean equals = getCommandType() == other.getCommandType() && {
entityType == other.entityType && return true;
indexNameId == other.indexNameId && }
keyId == other.keyId && if ( o == null || getClass() != o.getClass() )
getValueType() == other.getValueType(); {
if ( !equals ) return false;
}
if ( !super.equals( o ) )
{ {
return false; return false;
} }
IndexCommand that = (IndexCommand) o;
return commandType == that.commandType &&
indexNameId == that.indexNameId &&
entityType == that.entityType &&
entityId == that.entityId &&
keyId == that.keyId &&
valueType == that.valueType &&
Objects.equals( value, that.value );
}


return value == null ? other.value == null : value.equals( other.value ); @Override
public int hashCode()
{
return Objects.hash( super.hashCode(), commandType, indexNameId, entityType, entityId, keyId, valueType, value );
} }


public byte getCommandType() public byte getCommandType()
Expand Down
Expand Up @@ -22,6 +22,7 @@
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;


import org.neo4j.collection.primitive.Primitive; import org.neo4j.collection.primitive.Primitive;
Expand All @@ -31,7 +32,6 @@
import org.neo4j.kernel.impl.transaction.command.NeoCommandHandler; import org.neo4j.kernel.impl.transaction.command.NeoCommandHandler;


import static java.lang.String.format; import static java.lang.String.format;

import static org.neo4j.collection.primitive.Primitive.intObjectMap; import static org.neo4j.collection.primitive.Primitive.intObjectMap;


/** /**
Expand Down Expand Up @@ -142,25 +142,35 @@ private int getOrAssignId( Map<String,Integer> stringToId, PrimitiveIntObjectMap
return id; return id;
} }



@Override @Override
public int hashCode() public boolean equals( Object o )
{ {
int result = nextIndexNameId != null ? nextIndexNameId.hashCode() : 0; if ( this == o )
result = 31 * result + (nextKeyId != null ? nextKeyId.hashCode() : 0); {
result = 31 * result + (getIndexNameIdRange() != null ? getIndexNameIdRange().hashCode() : 0); return true;
result = 31 * result + (getKeyIdRange() != null ? getKeyIdRange().hashCode() : 0); }
result = 31 * result + (idToIndexName != null ? idToIndexName.hashCode() : 0); if ( o == null || getClass() != o.getClass() )
result = 31 * result + (idToKey != null ? idToKey.hashCode() : 0); {
return result; return false;
}
if ( !super.equals( o ) )
{
return false;
}
IndexDefineCommand that = (IndexDefineCommand) o;
return nextIndexNameId.get() == that.nextIndexNameId.get() &&
nextKeyId.get() == that.nextKeyId.get() &&
Objects.equals( indexNameIdRange, that.indexNameIdRange ) &&
Objects.equals( keyIdRange, that.keyIdRange ) &&
Objects.equals( idToIndexName, that.idToIndexName ) &&
Objects.equals( idToKey, that.idToKey );
} }


@Override @Override
public boolean equals( Object obj ) public int hashCode()
{ {
IndexDefineCommand other = (IndexDefineCommand) obj; return Objects.hash( super.hashCode(), nextIndexNameId.get(), nextKeyId.get(), indexNameIdRange, keyIdRange,
return getIndexNameIdRange().equals( other.getIndexNameIdRange() ) && idToIndexName, idToKey );
getKeyIdRange().equals( other.getKeyIdRange() );
} }


@Override @Override
Expand Down

0 comments on commit 035526d

Please sign in to comment.