Skip to content

Commit

Permalink
New ConstraintRule serialization + lengthOf methods
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Feb 9, 2017
1 parent 381cfd3 commit 26fa27d
Show file tree
Hide file tree
Showing 5 changed files with 374 additions and 71 deletions.
Expand Up @@ -19,6 +19,7 @@
*/
package org.neo4j.kernel.api.schema_new.constaints;

import org.neo4j.kernel.api.schema_new.SchemaDescriptor;
import org.neo4j.kernel.api.schema_new.SchemaDescriptorFactory;

import static org.neo4j.kernel.api.schema_new.constaints.ConstraintDescriptor.Type.EXISTS;
Expand All @@ -28,21 +29,31 @@ public class ConstraintDescriptorFactory
{
public static ConstraintDescriptor existsForLabel( int labelId, int... propertyIds )
{
return new ConstraintDescriptor( SchemaDescriptorFactory.forLabel( labelId, propertyIds ), EXISTS );
return existsForSchema( SchemaDescriptorFactory.forLabel( labelId, propertyIds ) );
}

public static ConstraintDescriptor existsForRelType( int relTypeId, int... propertyIds )
{
return new ConstraintDescriptor( SchemaDescriptorFactory.forRelType( relTypeId, propertyIds ), EXISTS );
return existsForSchema( SchemaDescriptorFactory.forRelType( relTypeId, propertyIds ) );
}

public static ConstraintDescriptor uniqueForLabel( int labelId, int... propertyIds )
{
return new ConstraintDescriptor( SchemaDescriptorFactory.forLabel( labelId, propertyIds ), UNIQUE );
return uniqueForSchema( SchemaDescriptorFactory.forLabel( labelId, propertyIds ) );
}

public static ConstraintDescriptor uniqueForRelType( int relTypeId, int... propertyIds )
{
return new ConstraintDescriptor( SchemaDescriptorFactory.forRelType( relTypeId, propertyIds ), UNIQUE );
return uniqueForSchema( SchemaDescriptorFactory.forRelType( relTypeId, propertyIds ) );
}

public static ConstraintDescriptor existsForSchema( SchemaDescriptor schema )
{
return new ConstraintDescriptor( schema, EXISTS );
}

public static ConstraintDescriptor uniqueForSchema( SchemaDescriptor schema )
{
return new ConstraintDescriptor( schema, UNIQUE );
}
}
Expand Up @@ -25,9 +25,12 @@
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.schema_new.LabelSchemaDescriptor;
import org.neo4j.kernel.api.schema_new.RelationTypeSchemaDescriptor;
import org.neo4j.kernel.api.schema_new.SchemaComputer;
import org.neo4j.kernel.api.schema_new.SchemaDescriptor;
import org.neo4j.kernel.api.schema_new.SchemaDescriptorFactory;
import org.neo4j.kernel.api.schema_new.SchemaProcessor;
import org.neo4j.kernel.api.schema_new.constaints.ConstraintDescriptor;
import org.neo4j.kernel.api.schema_new.constaints.ConstraintDescriptorFactory;
import org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor;
import org.neo4j.kernel.api.schema_new.index.NewIndexDescriptorFactory;
import org.neo4j.storageengine.api.schema.SchemaRule;
Expand All @@ -42,27 +45,161 @@ public class SchemaRuleSerialization
private final static byte INDEX_RULE = 1, CONSTRAINT_RULE = 2;

// Index type
private final static byte GENERAL_INDEX = 51, UNIQUE_INDEX = 52;
private final static byte GENERAL_INDEX = 31, UNIQUE_INDEX = 32;

// Constraint type
private final static byte EXISTS_CONSTRAINT = 61, UNIQUE_CONSTRAINT = 62;

// Schema type
private final static byte SIMPLE_LABEL = 101, SIMPLE_REL_TYPE = 102;
private final static byte SIMPLE_LABEL = 91, SIMPLE_REL_TYPE = 92;

private SchemaRuleSerialization()
{
}

// PUBLIC

/**
* Parse a SchemaRule from the provided buffer.
* @param id the id to give the returned Schema Rule
* @param source the buffer to parse from
* @return a SchemaRule
* @throws MalformedSchemaRuleException if bytes in the buffer do encode a valid SchemaRule
*/
public static SchemaRule deserialize( long id, ByteBuffer source ) throws MalformedSchemaRuleException
{
byte schemaRuleType = source.get();
switch ( schemaRuleType )
{
case INDEX_RULE:
return readIndexRule( id, source );
case CONSTRAINT_RULE:
return readConstraintRule( id, source );
}
throw new UnsupportedOperationException( format( "Got unknown schema rule type '%d'.", schemaRuleType ) );
}

/**
* Serialize the provided IndexRule onto the target buffer
* @param indexRule the IndexRule to serialize
* @param target the target buffer
* @throws MalformedSchemaRuleException if the IndexRule is of type unique, but the owning constrain
* has not been set
*/
public static void serialize( IndexRule indexRule, ByteBuffer target ) throws MalformedSchemaRuleException
{
target.put( INDEX_RULE );

SchemaIndexProvider.Descriptor providerDescriptor = indexRule.getProviderDescriptor();
UTF8.putEncodedStringInto( providerDescriptor.getKey(), target );
UTF8.putEncodedStringInto( providerDescriptor.getVersion(), target );

NewIndexDescriptor indexDescriptor = indexRule.getIndexDescriptor();
switch ( indexDescriptor.type() )
{
case GENERAL:
target.put( GENERAL_INDEX );
break;

case UNIQUE:
target.put( UNIQUE_INDEX );
Long owningConstraint = indexRule.getOwningConstraint();
if ( owningConstraint == null )
{
throw new MalformedSchemaRuleException( "Cannot serialize Unique Index before the owning constraint is set." );
}
target.putLong( owningConstraint );
break;

default:
throw new UnsupportedOperationException( format( "Got unknown index descriptor type '%s'.",
indexDescriptor.type() ) );
}

indexDescriptor.schema().processWith( new SchemaDescriptorSerializer( target ) );
}

/**
* Serialize the provided ConstraintRule onto the target buffer
* @param constraintRule the ConstraintRule to serialize
* @param target the target buffer
* @throws MalformedSchemaRuleException if the ConstraintRule is of type unique, but the owned index
* has not been set
*/
public static void serialize( ConstraintRule constraintRule, ByteBuffer target ) throws MalformedSchemaRuleException
{
target.put( CONSTRAINT_RULE );

ConstraintDescriptor constraintDescriptor = constraintRule.getConstraintDescriptor();
switch ( constraintDescriptor.type() )
{
case EXISTS:
target.put( EXISTS_CONSTRAINT );
break;

case UNIQUE:
target.put( UNIQUE_CONSTRAINT );
target.putLong( constraintRule.getOwnedIndex() );
break;

default:
throw new UnsupportedOperationException( format( "Got unknown schema rule type '%d'.", schemaRuleType ) );
throw new UnsupportedOperationException( format( "Got unknown index descriptor type '%s'.",
constraintDescriptor.type() ) );
}

constraintDescriptor.schema().processWith( new SchemaDescriptorSerializer( target ) );
}

/**
* Compute the byte size needed to serialize the provided IndexRule using serialize.
* @param indexRule the IndexRule
* @return the byte size of indexRule
*/
public static int lengthOf( IndexRule indexRule )
{
int length = 1; // schema rule type

SchemaIndexProvider.Descriptor providerDescriptor = indexRule.getProviderDescriptor();
length += UTF8.computeRequiredByteBufferSize( providerDescriptor.getKey() );
length += UTF8.computeRequiredByteBufferSize( providerDescriptor.getVersion() );

length += 1; // index type
NewIndexDescriptor indexDescriptor = indexRule.getIndexDescriptor();
switch ( indexDescriptor.type() )
{
case UNIQUE:
length += 8; // owning constraint id
}

length += schemaSizeComputer.compute( indexDescriptor.schema() );
return length;
}

/**
* Compute the byte size needed to serialize the provided ConstraintRule using serialize.
* @param constraintRule the ConstraintRule
* @return the byte size of ConstraintRule
*/
public static int lengthOf( ConstraintRule constraintRule )
{
int length = 1; // schema rule type

length += 1; // constraint type
ConstraintDescriptor constraintDescriptor = constraintRule.getConstraintDescriptor();
switch ( constraintDescriptor.type() )
{
case UNIQUE:
length += 8; // owned index id
}

length += schemaSizeComputer.compute( constraintDescriptor.schema() );
return length;
}

// PRIVATE

// READ INDEX

private static IndexRule readIndexRule( long id, ByteBuffer source ) throws MalformedSchemaRuleException
{
SchemaIndexProvider.Descriptor indexProvider = readIndexProviderDescriptor( source );
Expand All @@ -84,10 +221,9 @@ private static IndexRule readIndexRule( long id, ByteBuffer source ) throws Malf
indexProvider,
owningConstraint
);

default:
throw new UnsupportedOperationException( format( "Got unknown index rule type '%d'.", indexRuleType ) );
}

throw new MalformedSchemaRuleException( format( "Got unknown index rule type '%d'.", indexRuleType ) );
}

private static LabelSchemaDescriptor readLabelSchema( ByteBuffer source ) throws MalformedSchemaRuleException
Expand All @@ -101,13 +237,49 @@ private static LabelSchemaDescriptor readLabelSchema( ByteBuffer source ) throws
return (LabelSchemaDescriptor)schemaDescriptor;
}

private static SchemaIndexProvider.Descriptor readIndexProviderDescriptor( ByteBuffer source )
{
String providerKey = getDecodedStringFrom( source );
String providerVersion = getDecodedStringFrom( source );
return new SchemaIndexProvider.Descriptor( providerKey, providerVersion );
}

// READ CONSTRAINT

private static ConstraintRule readConstraintRule( long id, ByteBuffer source ) throws MalformedSchemaRuleException
{
byte constraintRuleType = source.get();
switch ( constraintRuleType )
{
case EXISTS_CONSTRAINT:
return ConstraintRule.constraintRule(
id,
ConstraintDescriptorFactory.existsForSchema( readSchema( source ) )
);

case UNIQUE_CONSTRAINT:
long ownedIndex = source.getLong();
return ConstraintRule.constraintRule(
id,
ConstraintDescriptorFactory.uniqueForSchema( readSchema( source ) ),
ownedIndex
);
}

throw new MalformedSchemaRuleException( format( "Got unknown constraint rule type '%d'.", constraintRuleType ) );
}

// READ HELP

private static SchemaDescriptor readSchema( ByteBuffer source )
{
byte schemaDescriptorType = source.get();
switch ( schemaDescriptorType )
{
case SIMPLE_LABEL:
return SchemaDescriptorFactory.forLabel( source.getInt(), readPropertyIds( source ) );
case SIMPLE_REL_TYPE:
return SchemaDescriptorFactory.forRelType( source.getInt(), readPropertyIds( source ) );
default:
throw new UnsupportedOperationException( format( "Got unknown schema descriptor type '%d'.",
schemaDescriptorType ) );
Expand All @@ -125,45 +297,7 @@ private static int[] readPropertyIds( ByteBuffer source )
return propertyIds;
}

private static SchemaIndexProvider.Descriptor readIndexProviderDescriptor( ByteBuffer source )
{
String providerKey = getDecodedStringFrom( source );
String providerVersion = getDecodedStringFrom( source );
return new SchemaIndexProvider.Descriptor( providerKey, providerVersion );
}

public static void serialize( IndexRule indexRule, ByteBuffer target ) throws MalformedSchemaRuleException
{
target.put( INDEX_RULE );

SchemaIndexProvider.Descriptor providerDescriptor = indexRule.getProviderDescriptor();
UTF8.putEncodedStringInto( providerDescriptor.getKey(), target );
UTF8.putEncodedStringInto( providerDescriptor.getVersion(), target );

NewIndexDescriptor indexDescriptor = indexRule.getIndexDescriptor();
switch ( indexDescriptor.type() )
{
case GENERAL:
target.put( GENERAL_INDEX );
break;

case UNIQUE:
target.put( UNIQUE_INDEX );
Long owningConstraint = indexRule.getOwningConstraint();
if ( owningConstraint == null )
{
throw new MalformedSchemaRuleException( "Cannot serialize Unique Index before the owning constraint is set." );
}
target.putLong( owningConstraint );
break;

default:
throw new UnsupportedOperationException( format( "Got unknown index descriptor type '%s'.",
indexDescriptor.type() ) );
}

indexDescriptor.schema().processWith( new SchemaDescriptorSerializer( target ) );
}
// WRITE

private static class SchemaDescriptorSerializer implements SchemaProcessor
{
Expand Down Expand Up @@ -202,4 +336,27 @@ public void processSpecific( RelationTypeSchemaDescriptor schema )
}
}
}

// LENGTH OF

private static SchemaComputer<Integer> schemaSizeComputer = new SchemaComputer<Integer>()
{
@Override
public Integer computeSpecific( LabelSchemaDescriptor schema )
{
return 1 // schema descriptor type
+ 4 // label id
+ 2 // property id count
+ 4 * schema.getPropertyIds().length; // the actual property ids
}

@Override
public Integer computeSpecific( RelationTypeSchemaDescriptor schema )
{
return 1 // schema descriptor type
+ 4 // rel type id
+ 2 // property id count
+ 4 * schema.getPropertyIds().length; // the actual property ids
}
};
}
Expand Up @@ -61,6 +61,20 @@ public void shouldCreateUniqueConstraintDescriptors()
assertThat( desc.schema(), equalTo( SchemaDescriptorFactory.forRelType( REL_TYPE_ID, 1 ) ) );
}

@Test
public void shouldCreateConstraintDescriptorsFromSchema()
{
ConstraintDescriptor desc;

desc = ConstraintDescriptorFactory.uniqueForSchema( SchemaDescriptorFactory.forLabel( LABEL_ID, 1 ) );
assertThat( desc.type(), equalTo( ConstraintDescriptor.Type.UNIQUE ) );
assertThat( desc.schema(), equalTo( SchemaDescriptorFactory.forLabel( LABEL_ID, 1 ) ) );

desc = ConstraintDescriptorFactory.existsForSchema( SchemaDescriptorFactory.forRelType( REL_TYPE_ID, 1 ) );
assertThat( desc.type(), equalTo( ConstraintDescriptor.Type.EXISTS) );
assertThat( desc.schema(), equalTo( SchemaDescriptorFactory.forRelType( REL_TYPE_ID, 1 ) ) );
}

@Test
public void shouldCreateEqualDescriptors()
{
Expand Down

0 comments on commit 26fa27d

Please sign in to comment.