Skip to content

Commit

Permalink
Make identifiers unique per entity
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobias Hafner committed Dec 22, 2024
1 parent 745d162 commit 727c936
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ public Result implement( EnumerableAlgImplementor implementor, Prefer pref ) {
final PhysType physType = result.physType();

Expression input_ = builder.append( "input", result.block() );
Expression identification_ = builder.append( "identification", Expressions.call( input_, BuiltInMethod.ADD_REL_IDENTIFIERS.method ) );
Expression entity_ = Expressions.constant(entity);
Expression identification_ = builder.append( "identification", Expressions.call(BuiltInMethod.ADD_REL_IDENTIFIERS.method, input_, entity_ ) );

builder.add( Expressions.return_( null, identification_ ) );

return implementor.result( physType, builder.toBlock() );

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@

import org.polypheny.db.algebra.AlgNode;
import org.polypheny.db.algebra.convert.ConverterRule;
import org.polypheny.db.algebra.core.AlgFactories;
import org.polypheny.db.algebra.logical.relational.LogicalRelIdentifier;
import org.polypheny.db.plan.AlgTraitSet;
import org.polypheny.db.plan.Convention;

public class EnumerableRelIdentifierRule extends ConverterRule {

EnumerableRelIdentifierRule() {
super( LogicalRelIdentifier.class, Convention.NONE, EnumerableConvention.INSTANCE, "EnumerableRelIdentifierRule" );
super( LogicalRelIdentifier.class, operand -> true, Convention.NONE, EnumerableConvention.INSTANCE, AlgFactories.LOGICAL_BUILDER,"EnumerableRelIdentifierRule" );
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public Result implement( EnumerableAlgImplementor implementor, Prefer pref ) {
final PhysType physType = result.physType();

Expression input_ = builder.append( "input", result.block() );
Expression identification_ = builder.append( "identification", Expressions.call( input_, BuiltInMethod.ADD_DOC_IDENTIFIERS.method ) );
Expression entity_ = Expressions.constant(entity);
Expression identification_ = builder.append( "identification", Expressions.call(BuiltInMethod.ADD_REL_IDENTIFIERS.method, input_, entity_ ) );

builder.add( Expressions.return_( null, identification_ ) );
return implementor.result( physType, builder.toBlock() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ public Result implement( EnumerableAlgImplementor implementor, Prefer pref ) {
final PhysType physType = result.physType();

Expression input_ = builder.append( "input", result.block() );
Expression identification_ = builder.append( "identification", Expressions.call( input_, BuiltInMethod.ADD_LPG_IDENTIFIERS.method ) );
Expression entity_ = Expressions.constant(entity);
Expression identification_ = builder.append( "identification", Expressions.call(BuiltInMethod.ADD_REL_IDENTIFIERS.method, input_, entity_ ) );

builder.add( Expressions.return_( null, identification_ ) );
return implementor.result( physType, builder.toBlock() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
import org.polypheny.db.schema.Statistics;
import org.polypheny.db.schema.types.Expressible;
import org.polypheny.db.schema.types.Typed;
import org.polypheny.db.transaction.locking.Lockable;
import org.polypheny.db.transaction.locking.EntityIdentifierRegistry;
import org.polypheny.db.transaction.locking.LockableObject;
import org.polypheny.db.util.ImmutableBitSet;
import org.polypheny.db.util.Wrapper;
Expand Down Expand Up @@ -72,6 +72,8 @@ public abstract class Entity implements PolyObject, Wrapper, Serializable, Catal
@JsonProperty
public boolean modifiable;

public EntityIdentifierRegistry entryIdentifiers;


public Entity(
long id,
Expand All @@ -86,6 +88,7 @@ public Entity(
this.entityType = type;
this.dataModel = dataModel;
this.modifiable = modifiable;
this.entryIdentifiers = new EntityIdentifierRegistry();
}


Expand All @@ -97,7 +100,8 @@ public AlgDataType getTupleType() {
};
}

public AlgDataType getTupleType(boolean hideIdentifier) {

public AlgDataType getTupleType( boolean hideIdentifier ) {
return switch ( dataModel ) {
case RELATIONAL -> throw new UnsupportedOperationException( "Should be overwritten by child" );
//TODO TH: adjust where necessary
Expand Down Expand Up @@ -172,6 +176,7 @@ public int compareTo( @NotNull Entity o ) {
return Long.compare( this.id, o.id );
}


public ObjectType getLockableObjectType() {
throw new UnsupportedOperationException( "Should be overwritten by child" );
}
Expand Down
10 changes: 5 additions & 5 deletions core/src/main/java/org/polypheny/db/functions/Functions.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@
import org.polypheny.db.algebra.type.AlgDataType;
import org.polypheny.db.algebra.type.AlgDataTypeFactory;
import org.polypheny.db.algebra.type.AlgDataTypeSystem;
import org.polypheny.db.catalog.entity.Entity;
import org.polypheny.db.catalog.exceptions.GenericRuntimeException;
import org.polypheny.db.functions.util.ProductPolyListEnumerator;
import org.polypheny.db.interpreter.Row;
import org.polypheny.db.runtime.ComparableList;
import org.polypheny.db.runtime.Like;
import org.polypheny.db.transaction.locking.IdentifierRegistry;
import org.polypheny.db.transaction.locking.IdentifierUtils;
import org.polypheny.db.type.PolyType;
import org.polypheny.db.type.PolyTypeFactoryImpl;
Expand Down Expand Up @@ -291,20 +291,20 @@ public static Enumerable<?> batch( final DataContext context, final Enumerable<P
}

@SuppressWarnings("unused")
public static Enumerable<PolyValue[]> addRelIdentifiers(final Enumerable<PolyValue[]> input) {
public static Enumerable<PolyValue[]> addRelIdentifiers(final Enumerable<PolyValue[]> input, Entity entity) {
return input.select( oldRow -> {
PolyValue[] newRow = new PolyValue[oldRow.length + 1];
newRow[0] = IdentifierUtils.getIdentifierAsPolyLong();
newRow[0] = entity.getEntryIdentifiers().getNextEntryIdentifierAsPolyLong();
System.arraycopy( oldRow, 0, newRow, 1, oldRow.length );
return newRow;
} );
}

@SuppressWarnings("unused")
public static Enumerable<PolyValue[]> addDocIdentifiers(final Enumerable<PolyValue[]> input) {
public static Enumerable<PolyValue[]> addDocIdentifiers(final Enumerable<PolyValue[]> input, Entity entity) {
return input.select( oldRow -> {
PolyDocument document = (PolyDocument) oldRow[0];
document.put( IdentifierUtils.getIdentifierKeyAsPolyString(), IdentifierUtils.getIdentifierAsPolyLong() );
document.put( IdentifierUtils.getIdentifierKeyAsPolyString(), entity.getEntryIdentifiers().getNextEntryIdentifierAsPolyLong() );
return new PolyValue[]{document};
} );
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
package org.polypheny.db.transaction.locking;

import java.math.BigDecimal;
import java.util.Set;
import java.util.TreeSet;
import org.polypheny.db.algebra.type.AlgDataTypeFactoryImpl;
import org.polypheny.db.rex.RexBuilder;
import org.polypheny.db.rex.RexLiteral;
import org.polypheny.db.type.entity.numerical.PolyLong;

public class IdentifierRegistry {
public class EntityIdentifierRegistry {

private static final Long MAX_IDENTIFIER_VALUE = Long.MAX_VALUE;
public static final IdentifierRegistry INSTANCE = new IdentifierRegistry( MAX_IDENTIFIER_VALUE );

private static final RexBuilder REX_BUILDER = new RexBuilder( AlgDataTypeFactoryImpl.DEFAULT );
private final TreeSet<IdentifierInterval> availableIdentifiers;


IdentifierRegistry( long maxIdentifierValue ) {
public EntityIdentifierRegistry() {
this.availableIdentifiers = new TreeSet<>();
this.availableIdentifiers.add( new IdentifierInterval( IdentifierUtils.MISSING_IDENTIFIER + 1, MAX_IDENTIFIER_VALUE ) );
}

public EntityIdentifierRegistry(long maxIdentifierValue) {
this.availableIdentifiers = new TreeSet<>();
this.availableIdentifiers.add( new IdentifierInterval( IdentifierUtils.MISSING_IDENTIFIER + 1, maxIdentifierValue ) );
}


public long getEntryIdentifier() {
public long getNextEntryIdentifier() {
while ( !availableIdentifiers.first().hasNextIdentifier() ) {
availableIdentifiers.pollFirst();
if ( availableIdentifiers.isEmpty() ) {
Expand All @@ -27,6 +36,15 @@ public long getEntryIdentifier() {
return availableIdentifiers.first().getNextIdentifier();
}

public RexLiteral getNextEntryIdentifierAsLiteral() {
return REX_BUILDER.makeExactLiteral( BigDecimal.valueOf( getNextEntryIdentifier() ) );
}


public PolyLong getNextEntryIdentifierAsPolyLong() {
return PolyLong.of( getNextEntryIdentifier() );
}


public void releaseEntryIdentifiers( Set<Long> identifiers ) {
if ( identifiers.isEmpty() ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,17 @@

package org.polypheny.db.transaction.locking;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.polypheny.db.algebra.type.AlgDataType;
import org.polypheny.db.algebra.type.AlgDataTypeFactoryImpl;
import org.polypheny.db.catalog.entity.Entity;
import org.polypheny.db.catalog.logistic.Collation;
import org.polypheny.db.ddl.DdlManager.ColumnTypeInformation;
import org.polypheny.db.ddl.DdlManager.FieldInformation;
import org.polypheny.db.rex.RexBuilder;
import org.polypheny.db.rex.RexLiteral;
import org.polypheny.db.type.PolyType;
import org.polypheny.db.type.PolyTypeFactoryImpl;
import org.polypheny.db.type.entity.PolyString;
Expand Down Expand Up @@ -59,16 +57,12 @@ public class IdentifierUtils {
1
);

private static final RexBuilder REX_BUILDER = new RexBuilder( AlgDataTypeFactoryImpl.DEFAULT );


public static RexLiteral getIdentifierAsLiteral() {
return REX_BUILDER.makeExactLiteral( BigDecimal.valueOf( IdentifierRegistry.INSTANCE.getEntryIdentifier() ) );
}


public static PolyLong getIdentifierAsPolyLong() {
return PolyLong.of( IdentifierRegistry.INSTANCE.getEntryIdentifier() );
public static PolyLong getIdentifierAsPolyLong( Entity entity) {
return PolyLong.of( entity.getEntryIdentifiers().getNextEntryIdentifier() );
}


Expand Down
7 changes: 4 additions & 3 deletions core/src/main/java/org/polypheny/db/util/BuiltInMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
import org.polypheny.db.algebra.metadata.BuiltInMetadata.TupleCount;
import org.polypheny.db.algebra.metadata.BuiltInMetadata.UniqueKeys;
import org.polypheny.db.algebra.metadata.Metadata;
import org.polypheny.db.catalog.entity.Entity;
import org.polypheny.db.catalog.snapshot.Snapshot;
import org.polypheny.db.functions.CrossModelFunctions;
import org.polypheny.db.functions.CypherFunctions;
Expand Down Expand Up @@ -155,9 +156,9 @@ public enum BuiltInMethod {
SWITCH_CONTEXT( DataContext.class, "switchContext" ),
BATCH( Functions.class, "batch", DataContext.class, Enumerable.class ),
STREAM_RIGHT( Functions.class, "streamRight", DataContext.class, Enumerable.class, Function0.class, List.class ),
ADD_REL_IDENTIFIERS(Functions.class, "addRelIdentifiers", Enumerable.class),
ADD_DOC_IDENTIFIERS(Functions.class, "addDocIdentifiers", Enumerable.class),
ADD_LPG_IDENTIFIERS(Functions.class, "addLpgIdentifiers", Enumerable.class),
ADD_REL_IDENTIFIERS(Functions.class, "addRelIdentifiers", Enumerable.class, Entity.class),
ADD_DOC_IDENTIFIERS(Functions.class, "addDocIdentifiers", Enumerable.class, Entity.class),
ADD_LPG_IDENTIFIERS(Functions.class, "addLpgIdentifiers", Enumerable.class, Entity.class),
ENFORCE_CONSTRAINT( Functions.class, "enforceConstraint", DataContext.class, Function0.class, Function0.class, List.class, List.class ),
PARSE_ARRAY_FROM_TEXT( Functions.class, "reparse", String.class ),
QUERYABLE_SELECT( Queryable.class, "select", FunctionExpression.class ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,76 +24,76 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class IdentifierRegistryTest {
public class EntityIdentifierRegistryTest {

private IdentifierRegistry registry;
private EntityIdentifierRegistry registry;


@BeforeEach
void setUp() {
registry = new IdentifierRegistry( 100 );
registry = new EntityIdentifierRegistry( 100 );
}


@Test
void testGetEntryIdentifierSequential() {
long firstId = registry.getEntryIdentifier();
long secondId = registry.getEntryIdentifier();
void testGetNextEntryIdentifierSequential() {
long firstId = registry.getNextEntryIdentifier();
long secondId = registry.getNextEntryIdentifier();

assertEquals( 1, firstId );
assertEquals( 2, secondId );
}


@Test
void testGetEntryIdentifierUntilOverflow() {
void testGetNextEntryIdentifierUntilOverflow() {
for ( int i = 0; i < 99; i++ ) {
registry.getEntryIdentifier();
registry.getNextEntryIdentifier();
}
Exception exception = assertThrows( IllegalStateException.class, registry::getEntryIdentifier );
Exception exception = assertThrows( IllegalStateException.class, registry::getNextEntryIdentifier );
assertEquals( "No identifiers available", exception.getMessage() );
}


@Test
void testReleaseSingleIdentifierBeginning() {
long firstIdentifier = registry.getEntryIdentifier();
registry.getEntryIdentifier();
long firstIdentifier = registry.getNextEntryIdentifier();
registry.getNextEntryIdentifier();

registry.releaseEntryIdentifiers( Set.of( firstIdentifier ) );
assertEquals( 1, registry.getEntryIdentifier() );
assertEquals( 1, registry.getNextEntryIdentifier() );
}


@Test
void testReleaseSingleIdentifierMiddle() {
for ( int i = 0; i < 25; i++ ) {
registry.getEntryIdentifier();
registry.getNextEntryIdentifier();
}
long middleIdentifier = registry.getEntryIdentifier();
long middleIdentifier = registry.getNextEntryIdentifier();
for ( int i = 0; i < 25; i++ ) {
registry.getEntryIdentifier();
registry.getNextEntryIdentifier();
}
registry.releaseEntryIdentifiers( Set.of( middleIdentifier ) );
assertEquals( 26, registry.getEntryIdentifier() );
assertEquals( 26, registry.getNextEntryIdentifier() );
}


@Test
void testReleaseMultipleIdentifiersConsequtive() {
Set<Long> identifiers = new HashSet<>();
for ( int i = 0; i < 20; i++ ) {
registry.getEntryIdentifier();
registry.getNextEntryIdentifier();
}
for ( int i = 0; i < 20; i++ ) {
identifiers.add( registry.getEntryIdentifier() );
identifiers.add( registry.getNextEntryIdentifier() );
}
for ( int i = 0; i < 20; i++ ) {
registry.getEntryIdentifier();
registry.getNextEntryIdentifier();
}
registry.releaseEntryIdentifiers( identifiers );
for ( int i = 21; i < 40; i++ ) {
assertEquals( i, registry.getEntryIdentifier() );
assertEquals( i, registry.getNextEntryIdentifier() );
}
}

Expand All @@ -104,7 +104,7 @@ void testReleaseMultipleIdentifiersInterleaved() {
Set<Long> oddIdentifiers = new HashSet<>();

for ( int i = 0; i < 60; i++ ) {
long id = registry.getEntryIdentifier();
long id = registry.getNextEntryIdentifier();
if ( id % 2 == 0 ) {
evenIdentifiers.add( id );
continue;
Expand All @@ -115,7 +115,7 @@ void testReleaseMultipleIdentifiersInterleaved() {
registry.releaseEntryIdentifiers( evenIdentifiers );

for ( int i = 0; i < 30; i++ ) {
long id = registry.getEntryIdentifier();
long id = registry.getNextEntryIdentifier();
assertEquals( 0, id % 2);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ public class TransactionImpl implements Transaction, Comparable<Object> {
@Getter
private Set<Lockable> lockedEntities = new HashSet<>();

@Getter
private Set<Long> readSet = new HashSet<>();


TransactionImpl(
PolyXid xid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,11 @@
import lombok.Getter;
import org.bson.BsonArray;
import org.bson.BsonDocument;
import org.bson.BsonInt64;
import org.bson.BsonValue;
import org.jetbrains.annotations.Nullable;
import org.polypheny.db.catalog.exceptions.GenericRuntimeException;
import org.polypheny.db.languages.ParserPos;
import org.polypheny.db.languages.mql.Mql.Type;
import org.polypheny.db.transaction.locking.IdentifierRegistry;
import org.polypheny.db.transaction.locking.IdentifierUtils;


@Getter
Expand Down

0 comments on commit 727c936

Please sign in to comment.