Skip to content

Commit

Permalink
Use Value type for values in Lucene
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Jun 15, 2017
1 parent 1081fa4 commit b817103
Show file tree
Hide file tree
Showing 34 changed files with 458 additions and 163 deletions.
Expand Up @@ -23,6 +23,9 @@
import java.util.Base64;

import org.neo4j.string.UTF8;
import org.neo4j.values.Value;
import org.neo4j.values.ValueWriter;
import org.neo4j.values.Values;

public final class ArrayEncoder
{
Expand All @@ -33,6 +36,7 @@ private ArrayEncoder()
throw new AssertionError( "Not for instantiation!" );
}

@Deprecated
public static String encode( Object array )
{
if ( !array.getClass().isArray() )
Expand Down Expand Up @@ -66,4 +70,153 @@ else if ( o instanceof Boolean )
}
return type + builder.toString();
}

public static String encode( Value array )
{
if ( !Values.isArrayValue( array ) )
{
throw new IllegalArgumentException( "Only works with arrays" );
}

ValueEncoder encoder = new ValueEncoder();
array.writeTo( encoder );
return encoder.result();
}

static class ValueEncoder implements ValueWriter
{
StringBuilder builder;

ValueEncoder()
{
builder = new StringBuilder();
}

public String result()
{
return builder.toString();
}

@Override
public void writeNull()
{
}

@Override
public void writeBoolean( boolean value )
{
builder.append( value );
builder.append( '|' );
}

@Override
public void writeInteger( byte value )
{
builder.append( (double)value );
builder.append( '|' );
}

@Override
public void writeInteger( short value )
{
builder.append( (double)value );
builder.append( '|' );
}

@Override
public void writeInteger( int value )
{
builder.append( (double)value );
builder.append( '|' );
}

@Override
public void writeInteger( long value )
{
builder.append( (double)value );
builder.append( '|' );
}

@Override
public void writeFloatingPoint( float value )
{
builder.append( (double)value );
builder.append( '|' );
}

@Override
public void writeFloatingPoint( double value )
{
builder.append( value );
builder.append( '|' );
}

@Override
public void writeString( String value )
{
builder.append( value );
builder.append( '|' );
}

@Override
public void writeString( char value )
{
builder.append( value );
builder.append( '|' );
}

@Override
public void writeString( char[] value, int offset, int length )
{
builder.append( value, offset, length );
builder.append( '|' );
}

@Override
public void beginUTF8( int size )
{
throw new UnsupportedOperationException( "direct UTF8 encoding is not supported yet!" );
}

@Override
public void copyUTF8( long fromAddress, int length )
{
throw new UnsupportedOperationException( "direct UTF8 encoding is not supported yet!" );
}

@Override
public void endUTF8()
{
throw new UnsupportedOperationException( "direct UTF8 encoding is not supported yet!" );
}

@Override
public void beginArray( int size, ArrayType arrayType )
{
builder.append( typeChar( arrayType ) );
}

@Override
public void endArray()
{

}

private char typeChar( ArrayType arrayType )
{
switch ( arrayType )
{
case BOOLEAN: return 'Z';
case BYTE: return 'D';
case SHORT: return 'D';
case INT: return 'D';
case LONG: return 'D';
case FLOAT: return 'D';
case DOUBLE: return 'D';
case CHAR: return 'L';
case STRING: return 'L';
default: throw new UnsupportedOperationException( "Not supported array type: "+arrayType );
}
}
}
}
Expand Up @@ -20,26 +20,28 @@
package org.neo4j.kernel.impl.api;

import org.neo4j.kernel.impl.util.Validator;
import org.neo4j.values.TextValue;
import org.neo4j.values.Value;
import org.neo4j.values.Values;

public class IndexSimpleValueValidator implements Validator
public class IndexSimpleValueValidator implements Validator<Value>
{

public static IndexSimpleValueValidator INSTANCE = new IndexSimpleValueValidator();

private IndexSimpleValueValidator()
{
}

@Override
public void validate( Object value )
public void validate( Value value )
{
if ( value == null )
if ( value == null || value == Values.NO_VALUE )
{
throw new IllegalArgumentException( "Null value" );
}
if ( value instanceof String )
if ( Values.isTextValue( value ) )
{
IndexValueLengthValidator.INSTANCE.validate( ((String) value).getBytes() );
IndexValueLengthValidator.INSTANCE.validate( ((TextValue)value).stringValue().getBytes() );
}
}
}
Expand Up @@ -21,8 +21,10 @@

import org.neo4j.kernel.api.index.ArrayEncoder;
import org.neo4j.kernel.impl.util.Validator;
import org.neo4j.values.Value;
import org.neo4j.values.Values;

public class IndexValueValidator implements Validator
public class IndexValueValidator implements Validator<Value>
{
public static IndexValueValidator INSTANCE = new IndexValueValidator();

Expand All @@ -31,10 +33,10 @@ private IndexValueValidator()
}

@Override
public void validate( Object value )
public void validate( Value value )
{
IndexSimpleValueValidator.INSTANCE.validate( value );
if ( value.getClass().isArray() )
if ( Values.isArrayValue( value ) )
{
IndexValueLengthValidator.INSTANCE.validate( ArrayEncoder.encode( value ).getBytes() );
}
Expand Down
Expand Up @@ -21,7 +21,7 @@

import org.neo4j.kernel.impl.util.Validator;

public class LegacyIndexValueValidator implements Validator
public class LegacyIndexValueValidator implements Validator<Object>
{
public static LegacyIndexValueValidator INSTANCE = new LegacyIndexValueValidator();

Expand All @@ -32,7 +32,14 @@ private LegacyIndexValueValidator()
@Override
public void validate( Object value )
{
IndexSimpleValueValidator.INSTANCE.validate( value );
if ( value == null )
{
throw new IllegalArgumentException( "Null value" );
}
if ( value instanceof String )
{
IndexValueLengthValidator.INSTANCE.validate( ((String)value).getBytes() );
}
if ( !(value instanceof Number) && value.toString() == null )
{
throw new IllegalArgumentException( "Value of type " + value.getClass() + " has null toString" );
Expand Down
Expand Up @@ -25,6 +25,7 @@
import org.junit.rules.ExpectedException;

import org.neo4j.kernel.impl.util.Validator;
import org.neo4j.values.Values;

import static org.neo4j.kernel.impl.api.IndexSimpleValueValidator.INSTANCE;

Expand Down Expand Up @@ -83,6 +84,6 @@ public void shortStringIsValidValue()

protected Validator<Object> getValidator()
{
return INSTANCE;
return object -> INSTANCE.validate( Values.of( object ) );
}
}
Expand Up @@ -23,6 +23,7 @@
import org.junit.Test;

import org.neo4j.kernel.impl.util.Validator;
import org.neo4j.values.Values;

public class IndexValueValidatorTest extends IndexSimpleValueValidatorTest
{
Expand All @@ -45,8 +46,8 @@ public void shortArrayIsAllowed() throws Exception
}

@Override
protected Validator getValidator()
protected Validator<Object> getValidator()
{
return IndexValueValidator.INSTANCE;
return object -> IndexValueValidator.INSTANCE.validate( Values.of( object ) );
}
}
Expand Up @@ -50,6 +50,7 @@
import java.util.Iterator;

import org.neo4j.unsafe.impl.internal.dragons.FeatureToggles;
import org.neo4j.values.Value;

import static org.apache.lucene.document.Field.Store.YES;

Expand All @@ -74,18 +75,18 @@ private static DocWithId reuseDocument( long nodeId )
return doc;
}

public static Document documentRepresentingProperties( long nodeId, Object... values )
public static Document documentRepresentingProperties( long nodeId, Value... values )
{
DocWithId document = reuseDocument( nodeId );
document.setValues( values );
return document.document;
}

public static String encodedStringValuesForSampling( Object... values )
public static String encodedStringValuesForSampling( Value... values )
{
StringBuilder sb = new StringBuilder();
String sep = "";
for ( Object value : values )
for ( Value value : values )
{
sb.append( sep );
sep = DELIMITER;
Expand All @@ -100,7 +101,7 @@ public static MatchAllDocsQuery newScanQuery()
return new MatchAllDocsQuery();
}

public static Query newSeekQuery( Object... values )
public static Query newSeekQuery( Value... values )
{
BooleanQuery.Builder builder = new BooleanQuery.Builder();
for ( int i = 0; i < values.length; i++ )
Expand Down Expand Up @@ -185,7 +186,7 @@ public static long getNodeId( Document from )

/**
* Filters the given {@link Terms terms} to include only terms that were created using fields from
* {@link ValueEncoding#encodeField(String,Object)}. Internal lucene terms like those created for indexing numeric values
* {@link ValueEncoding#encodeField(String, Value)}. Internal lucene terms like those created for indexing numeric values
* (see javadoc for {@link NumericRangeQuery} class) are skipped. In other words this method returns
* {@link TermsEnum} over all terms for the given field that were created using {@link ValueEncoding}.
*
Expand Down Expand Up @@ -253,7 +254,7 @@ protected AcceptStatus accept( BytesRef term ) throws IOException
}
}

public static Field encodeValueField( Object value )
public static Field encodeValueField( Value value )
{
ValueEncoding encoding = ValueEncoding.forValue( value );
return encoding.encodeField( encoding.key(), value );
Expand Down Expand Up @@ -283,7 +284,7 @@ private void setId( long id )
idValueField.setLongValue( id );
}

private void setValues( Object... values )
private void setValues( Value... values )
{
removeAllValueFields();
int neededLength = values.length * ValueEncoding.values().length;
Expand Down Expand Up @@ -313,7 +314,7 @@ private void removeAllValueFields()
}
}

private Field getFieldWithValue( int propertyNumber, Object value )
private Field getFieldWithValue( int propertyNumber, Value value )
{
ValueEncoding encoding = ValueEncoding.forValue( value );
int reuseId = propertyNumber * ValueEncoding.values().length + encoding.ordinal();
Expand Down
Expand Up @@ -35,6 +35,7 @@
import org.neo4j.kernel.api.schema.index.IndexDescriptor;
import org.neo4j.kernel.impl.api.index.IndexUpdateMode;
import org.neo4j.storageengine.api.schema.IndexReader;
import org.neo4j.values.Value;

public class LuceneIndexAccessor implements IndexAccessor
{
Expand Down Expand Up @@ -182,19 +183,19 @@ public void remove( PrimitiveLongSet nodeIds ) throws IOException
} );
}

private void addRecovered( long nodeId, Object[] values ) throws IOException
private void addRecovered( long nodeId, Value[] values ) throws IOException
{

writer.updateDocument( LuceneDocumentStructure.newTermForChangeOrRemove( nodeId ),
LuceneDocumentStructure.documentRepresentingProperties( nodeId, values ) );
}

private void add( long nodeId, Object[] values ) throws IOException
private void add( long nodeId, Value[] values ) throws IOException
{
writer.addDocument( LuceneDocumentStructure.documentRepresentingProperties( nodeId, values ) );
}

private void change( long nodeId, Object[] values ) throws IOException
private void change( long nodeId, Value[] values ) throws IOException
{
writer.updateDocument( LuceneDocumentStructure.newTermForChangeOrRemove( nodeId ),
LuceneDocumentStructure.documentRepresentingProperties( nodeId, values ) );
Expand Down

0 comments on commit b817103

Please sign in to comment.