Skip to content

Commit

Permalink
Added virtual value for extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed May 31, 2017
1 parent f956150 commit 367b8cf
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 9 deletions.
Expand Up @@ -29,10 +29,14 @@
class ValueComparator implements Comparator<Value>
{
private final Comparator<ValueGroup> valueGroupComparator;
private final Comparator<VirtualValue> virtualValueComparator;

ValueComparator( Comparator<ValueGroup> valueGroupComparator )
ValueComparator(
Comparator<ValueGroup> valueGroupComparator,
Comparator<VirtualValue> virtualValueComparator )
{
this.valueGroupComparator = valueGroupComparator;
this.virtualValueComparator = virtualValueComparator;
}

@Override
Expand Down Expand Up @@ -76,6 +80,9 @@ public int compare( Value v1, Value v2 )
case BOOLEAN_ARRAY:
return ((BooleanArray) v1).compareTo( (BooleanArray) v2 );

case VIRTUAL:
return virtualValueComparator.compare( (VirtualValue)v1, (VirtualValue)v2 );

default:
throw new UnsupportedOperationException( format( "Unknown ValueGroup id '%s'", id1 ) );
}
Expand Down
Expand Up @@ -33,7 +33,8 @@ public enum ValueGroup
INTEGER_ARRAY( 3 ),
FLOAT_ARRAY( 3 ),
TEXT_ARRAY( 4 ),
BOOLEAN_ARRAY( 5 );
BOOLEAN_ARRAY( 5 ),
VIRTUAL( 6 );

private final int comparabilityGroup;

Expand Down
11 changes: 11 additions & 0 deletions community/values/src/main/java/org/neo4j/values/Values.java
Expand Up @@ -20,6 +20,7 @@
package org.neo4j.values;

import java.lang.reflect.Array;
import java.util.Comparator;

/**
* Entry point to the values library.
Expand Down Expand Up @@ -49,6 +50,16 @@ public class ValueLoadException extends RuntimeException
{
}

/**
* Default value comparator. Will correctly compare all storable values and order the value groups according the
* to comparability group. Virtual values are sorted in a random but deterministic fashion (by hashCode).
*/
public static final ValueComparator VALUE_COMPARATOR =
new ValueComparator(
Comparator.comparingInt( ValueGroup::comparabilityGroup ),
Comparator.comparingInt( VirtualValue::hashCode )
);

// DIRECT FACTORY METHODS

public static final Value NO_VALUE = NoValue.NO_VALUE;
Expand Down
127 changes: 127 additions & 0 deletions community/values/src/main/java/org/neo4j/values/VirtualValue.java
@@ -0,0 +1,127 @@
/*
* Copyright (c) 2002-2017 "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.values;

/**
* Value that can exist transiently during computations, but that cannot be stored as a property value. A Virtual
* Value could be a NodeReference for example.
*/
public abstract class VirtualValue extends Value
{
@Override
public final boolean equals( byte[] x )
{
return false;
}

@Override
public final boolean equals( short[] x )
{
return false;
}

@Override
public final boolean equals( int[] x )
{
return false;
}

@Override
public final boolean equals( long[] x )
{
return false;
}

@Override
public final boolean equals( float[] x )
{
return false;
}

@Override
public final boolean equals( double[] x )
{
return false;
}

@Override
public final boolean equals( boolean x )
{
return false;
}

@Override
public final boolean equals( boolean[] x )
{
return false;
}

@Override
public final boolean equals( char x )
{
return false;
}

@Override
public final boolean equals( String x )
{
return false;
}

@Override
public final boolean equals( char[] x )
{
return false;
}

@Override
public final boolean equals( String[] x )
{
return false;
}

@Override
public final boolean equals( Object other )
{
return other != null && other instanceof VirtualValue && equals( (VirtualValue) other );
}

@Override
public final boolean equals( Value other )
{
return other != null && other instanceof VirtualValue && equals( (VirtualValue) other );
}

@Override
public final int hashCode()
{
return hash();
}

public abstract int hash();

public abstract boolean equals( VirtualValue other );

@Override
public final ValueGroup valueGroup()
{
return ValueGroup.VIRTUAL;
}
}
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2002-2017 "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.values;

public class MyVirtualValue extends VirtualValue
{
private final int hashCode;

MyVirtualValue( int hashCode )
{
this.hashCode = hashCode;
}

@Override
public boolean equals( VirtualValue other )
{
return this == other;
}

@Override
public int hash()
{
return hashCode;
}

@Override
public void writeTo( ValueWriter writer )
{
}

@Override
public Object asPublic()
{
return this;
}
}
Expand Up @@ -25,6 +25,8 @@

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static java.lang.String.format;

Expand All @@ -33,8 +35,7 @@ public class ValueComparisonTest
@Rule
public ExpectedException thrown = ExpectedException.none();

private ValueComparator comparator = new ValueComparator(
Comparator.comparingInt( ValueGroup::comparabilityGroup ) );
private ValueComparator comparator = Values.VALUE_COMPARATOR;

private Object[] objs = new Object[]{
// OTHER
Expand Down Expand Up @@ -92,14 +93,16 @@ public class ValueComparisonTest
@Test
public void shouldOrderValuesCorrectly()
{
Value[] values = Arrays.stream( objs ).map( Values::of ).toArray( Value[]::new );
List<Value> values = Arrays.stream( objs ).map( Values::of ).collect( Collectors.toList() );
values.add( new MyVirtualValue( 0 ) );
values.add( new MyVirtualValue( 1 ) );

for ( int i = 0; i < values.length; i++ )
for ( int i = 0; i < values.size(); i++ )
{
for ( int j = 0; j < values.length; j++ )
for ( int j = 0; j < values.size(); j++ )
{
Value left = values[i];
Value right = values[j];
Value left = values.get( i );
Value right = values.get( j );

int cmpPos = sign( i - j );
int cmpVal = sign( compare( comparator, left, right ) );
Expand Down
22 changes: 22 additions & 0 deletions community/values/src/test/java/org/neo4j/values/ValuesTest.java
Expand Up @@ -21,6 +21,7 @@

import org.junit.Test;

import static junit.framework.TestCase.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.neo4j.values.Values.booleanArray;
import static org.neo4j.values.Values.booleanValue;
Expand Down Expand Up @@ -118,10 +119,31 @@ public void shouldBeEqualToItself()
assertEqual( stringArray( new String[]{"hi"} ), lazyStringArray( () -> new String[]{"hi"} ) );
}

@Test
public void shouldNotEqualVirtualValue()
{
VirtualValue virtual = new MyVirtualValue( 42 );

assertNotEqual( booleanValue( false ), virtual );
assertNotEqual( byteValue( (byte)0 ), virtual );
assertNotEqual( shortValue( (short)0 ), virtual );
assertNotEqual( intValue( 0 ), virtual );
assertNotEqual( longValue( 0 ), virtual );
assertNotEqual( floatValue( 0.0f ), virtual );
assertNotEqual( doubleValue( 0.0 ), virtual );
assertNotEqual( stringValue( "" ), virtual );
}

private void assertEqual( Value a, Value b )
{
assertTrue( "should be equal", a.equals( b ) );
assertTrue( "should be equal", b.equals( a ) );
assertTrue( "should have same has", a.hashCode() == b.hashCode() );
}

private void assertNotEqual( Value a, Value b )
{
assertFalse( "should not be equal", a.equals( b ) );
assertFalse( "should not be equal", b.equals( a ) );
}
}

0 comments on commit 367b8cf

Please sign in to comment.