Skip to content

Commit

Permalink
equality of OrderedPropertyValues
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Mar 8, 2017
1 parent b668cf4 commit 796a19e
Show file tree
Hide file tree
Showing 27 changed files with 122 additions and 78 deletions.
Expand Up @@ -40,7 +40,7 @@ public class IndexEntryConflictException extends Exception

public IndexEntryConflictException( long existingNodeId, long addedNodeId, Object propertyValue )
{
this( existingNodeId, addedNodeId, OrderedPropertyValues.of( propertyValue ) );
this( existingNodeId, addedNodeId, OrderedPropertyValues.ofUndefined( propertyValue ) );
}

public IndexEntryConflictException( long existingNodeId, long addedNodeId, OrderedPropertyValues propertyValues )
Expand Down Expand Up @@ -150,7 +150,7 @@ private String propertyString( TokenNameLookup tokenNameLookup, int[] propertyId
sb.append( '`' );
sb.append( tokenNameLookup.propertyKeyGetName( propertyIds[i] ) );
sb.append( "` = " );
sb.append( OrderedPropertyValues.quote( propertyValues.values()[i] ) );
sb.append( OrderedPropertyValues.quote( propertyValues.valueAt( i ) ) );
}
return sb.toString();
}
Expand Down
Expand Up @@ -71,7 +71,7 @@ static boolean valueEquals( boolean[] value, Object other )
}

@Override
int valueHash()
public int valueHash()
{
return hash( value );
}
Expand Down
Expand Up @@ -47,7 +47,7 @@ public Boolean value()
}

@Override
int valueHash()
public int valueHash()
{
return value ? -1 : 0;
}
Expand Down
Expand Up @@ -75,7 +75,7 @@ else if ( other instanceof String[] )
}

@Override
int valueHash()
public int valueHash()
{
return hash( value );
}
Expand Down
Expand Up @@ -56,7 +56,7 @@ public Character value()
}

@Override
int valueHash()
public int valueHash()
{
return value;
}
Expand Down
Expand Up @@ -57,7 +57,7 @@ public Object value()
}

@Override
int valueHash()
public int valueHash()
{
return -1;
}
Expand Down Expand Up @@ -143,7 +143,7 @@ public final int hashCode()
return propertyKeyId ^ valueHash();
}

abstract int valueHash();
public abstract int valueHash();

/** We never pass {@link LazyProperty} to this method, since we check for it in {@link #equals(Object)}. */
abstract boolean hasEqualValue( DefinedProperty that );
Expand Down
Expand Up @@ -31,7 +31,7 @@ abstract class FloatingPointArrayProperty extends DefinedProperty implements Arr
public abstract double doubleValue( int index );

@Override
final int valueHash()
public final int valueHash()
{
return hash( this );
}
Expand Down
Expand Up @@ -29,7 +29,7 @@ abstract class FloatingPointNumberProperty extends NumberProperty
}

@Override
final int valueHash()
public final int valueHash()
{
long value = (long) doubleValue();
return (int) (value ^ (value >>> 32));
Expand Down
Expand Up @@ -31,7 +31,7 @@ abstract class IntegralArrayProperty extends DefinedProperty implements ArrayVal
public abstract long longValue( int index );

@Override
final int valueHash()
public final int valueHash()
{
return hash( this );
}
Expand Down
Expand Up @@ -33,7 +33,7 @@ public double doubleValue()
}

@Override
final int valueHash()
public final int valueHash()
{
long value = longValue();
return (int) (value ^ (value >>> 32));
Expand Down
Expand Up @@ -59,7 +59,7 @@ public boolean valueEquals( Object value )
}

@Override
int valueHash()
public int valueHash()
{
Object myValue = value(); // value() accesses LazyProperty.value, implying a read barrier ...
return type.hashCode( myValue ); // ... so accessing type is safe
Expand Down
Expand Up @@ -35,7 +35,7 @@ public boolean valueEquals( Object value )
}

@Override
int valueHash()
public int valueHash()
{
return value().hashCode();
}
Expand Down
Expand Up @@ -77,7 +77,7 @@ else if ( other instanceof Character[] )
}

@Override
int valueHash()
public int valueHash()
{
return hash( value );
}
Expand Down
Expand Up @@ -57,7 +57,7 @@ public String value()
}

@Override
int valueHash()
public int valueHash()
{
return value.hashCode();
}
Expand Down
Expand Up @@ -22,45 +22,62 @@
import java.util.Arrays;
import java.util.Comparator;

import org.neo4j.kernel.api.properties.DefinedProperty;
import org.neo4j.kernel.api.properties.Property;

import static org.neo4j.kernel.api.StatementConstants.NO_SUCH_PROPERTY_KEY;
import static org.neo4j.kernel.impl.api.PropertyValueComparison.COMPARE_VALUES;

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

/**
* Holder for n property values, ordered according to a schema descriptor property id order
*
* This implementation uses the Property class hierarchy to achieve correct equality between property values of
* different types. However, the propertyKeyId is really not needed and we could consider reimplementing the class if
* we make static methods for comparing property values.
*/
public class OrderedPropertyValues
{
// FACTORY METHODS

public static OrderedPropertyValues of( Object... values )
public static OrderedPropertyValues ofUndefined( Object... values )
{
return new OrderedPropertyValues(
Arrays.stream( values )
.map( value -> Property.property( NO_SUCH_PROPERTY_KEY, value ) )
.toArray( DefinedProperty[]::new )
);
}

public static OrderedPropertyValues of( DefinedProperty[] values )
{
return new OrderedPropertyValues( values );
}

public static OrderedPropertyValues of( IndexQuery.ExactPredicate[] exactPreds )
{
Object[] values = new Object[exactPreds.length];
DefinedProperty[] values = new DefinedProperty[exactPreds.length];
for ( int i = 0; i < exactPreds.length; i++ )
{
values[i] = exactPreds[i].value();
values[i] = Property.property( exactPreds[i].propertyKeyId(), exactPreds[i].value() );
}
return new OrderedPropertyValues( values );
}

// ACTUAL CLASS

private final Object[] values;
private final DefinedProperty[] properties;

private OrderedPropertyValues( Object[] values )
private OrderedPropertyValues( DefinedProperty[] properties )
{
this.values = values;
this.properties = properties;
}

public Object[] values()
public Object valueAt( int position )
{
return values;
return properties[position].value();
}

@Override
Expand All @@ -77,36 +94,53 @@ public boolean equals( Object o )

OrderedPropertyValues that = (OrderedPropertyValues) o;

return Arrays.deepEquals( values, that.values );
if ( that.properties.length != properties.length )
{
return false;
}

for ( int i = 0; i < properties.length; i++ )
{
if ( !properties[i].valueEquals( that.properties[i].value() ) )
{
return false;
}
}
return true;
}

@Override
public int hashCode()
{
return Arrays.deepHashCode( values );
int result = 0;
for ( DefinedProperty property : properties )
{
result = 31 * ( result + property.valueHash() );
}
return result;
}

public int size()
{
return values.length;
return properties.length;
}

public Object getSinglePropertyValue()
{
assert values.length == 1 : "Assumed single property but had " + values.length;
return values[0];
assert properties.length == 1 : "Assumed single property but had " + properties.length;
return properties[0].value();
}

@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
String sep = "( ";
for ( Object value : values )
for ( DefinedProperty property : properties )
{
sb.append( sep );
sep = ", ";
sb.append( quote( value ) );
sb.append( quote( property.value() ) );
}
sb.append( " )" );
return sb.toString();
Expand Down Expand Up @@ -155,15 +189,15 @@ else if ( propertyValue.getClass().isArray() )

public static final Comparator<OrderedPropertyValues> COMPARATOR = ( left, right ) ->
{
if ( left.values.length != right.values.length )
if ( left.properties.length != right.properties.length )
{
throw new IllegalStateException( "Comparing two OrderedPropertyValues of different lengths!" );
}

int compare = 0;
for ( int i = 0; i < left.values.length; i++ )
for ( int i = 0; i < left.properties.length; i++ )
{
compare = COMPARE_VALUES.compare( left.values[i], right.values[i] );
compare = COMPARE_VALUES.compare( left.properties[i].value(), right.properties[i].value() );
if ( compare != 0 )
{
return compare;
Expand Down
Expand Up @@ -63,6 +63,11 @@ public static PrimitiveLongIterator exactIndexMatches( PropertyAccessor accessor
public static PrimitiveLongIterator exactIndexMatches( EntityOperations operations, KernelStatement state,
PrimitiveLongIterator indexedNodeIds, IndexQuery... predicates )
{
if ( !indexedNodeIds.hasNext() )
{
return indexedNodeIds;
}

IndexQuery[] numericPredicates =
Arrays.stream( predicates )
.filter( LookupFilter::isNumericPredicate )
Expand Down
Expand Up @@ -24,9 +24,9 @@
import org.neo4j.collection.primitive.Primitive;
import org.neo4j.collection.primitive.PrimitiveIntSet;
import org.neo4j.helpers.collection.Iterators;
import org.neo4j.kernel.api.ReadOperations;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.kernel.api.properties.DefinedProperty;
import org.neo4j.kernel.api.properties.Property;
import org.neo4j.kernel.api.schema_new.LabelSchemaDescriptor;
import org.neo4j.kernel.api.schema_new.OrderedPropertyValues;
import org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor;
Expand Down Expand Up @@ -171,7 +171,7 @@ public void updateIndexIfApplicable( KernelStatement state, NodeItem node,
}
}
state.txState().indexDoUpdateEntry( index.schema(), node.id(),
OrderedPropertyValues.of( valuesBefore ), OrderedPropertyValues.of( valuesAfter ) );
OrderedPropertyValues.ofUndefined( valuesBefore ), OrderedPropertyValues.ofUndefined( valuesAfter ) );
}
}

Expand Down Expand Up @@ -211,8 +211,7 @@ private OrderedPropertyValues valuesIfPropertiesMatch( KernelStatement state, Pr
return valuesIfPropertiesMatch( state, nodeProperties, index, node, NO_SUCH_PROPERTY );
}

private OrderedPropertyValues valuesIfPropertiesMatch( KernelStatement state, PrimitiveIntSet
nodeProperties,
private OrderedPropertyValues valuesIfPropertiesMatch( KernelStatement state, PrimitiveIntSet nodeProperties,
NewIndexDescriptor index, NodeItem node, DefinedProperty changedProperty ) throws EntityNotFoundException
{
int[] indexPropertyIds = index.schema().getPropertyIds();
Expand All @@ -221,12 +220,13 @@ private OrderedPropertyValues valuesIfPropertiesMatch( KernelStatement state, Pr
return null;
}

Object[] values = new Object[indexPropertyIds.length];
DefinedProperty[] values = new DefinedProperty[indexPropertyIds.length];
for ( int i = 0; i < values.length; i++ )
{
int indexPropertyId = indexPropertyIds[i];
values[i] = indexPropertyId == changedProperty.propertyKeyId() ?
changedProperty.value() : readOps.nodeGetProperty( state, node, indexPropertyId );
values[i] = indexPropertyId == changedProperty.propertyKeyId()
? changedProperty
: Property.property( indexPropertyId, readOps.nodeGetProperty( state, node, indexPropertyId ) );
}

return OrderedPropertyValues.of( values );
Expand Down

0 comments on commit 796a19e

Please sign in to comment.