Skip to content

Commit a7d3860

Browse files
committed
More SchemaDescriptorLookupSet testing and minor comment addressed
Also Junit5-ified SchemaDescriptorLookupSetTest
1 parent 08a5162 commit a7d3860

File tree

4 files changed

+126
-36
lines changed

4 files changed

+126
-36
lines changed

community/kernel/src/main/java/org/neo4j/kernel/impl/api/index/EntityCommandGrouper.java

Lines changed: 1 addition & 1 deletion
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -115,7 +115,7 @@ public void clear()
115
* <ol>
115
* <ol>
116
* <li>Call {@link #nextEntity()} to go to the next group, if any</li>
116
* <li>Call {@link #nextEntity()} to go to the next group, if any</li>
117
* <li>A group may or may not have the entity command, as accessed by {@link #currentEntityCommand()},
117
* <li>A group may or may not have the entity command, as accessed by {@link #currentEntityCommand()},
118-
* either way the node id is accessible using {@link #currentEntityId()}</li>
118+
* either way the entity id is accessible using {@link #currentEntityId()}</li>
119
* <li>Call {@link #nextProperty()} until it returns null, now all the {@link PropertyCommand} in this group have been accessed</li>
119
* <li>Call {@link #nextProperty()} until it returns null, now all the {@link PropertyCommand} in this group have been accessed</li>
120
* </ol>
120
* </ol>
121
*/
121
*/

community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeSchemaMatcher.java

Lines changed: 2 additions & 1 deletion
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -49,6 +49,7 @@ private NodeSchemaMatcher()
49
* @param schemaSuppliers The suppliers to match
49
* @param schemaSuppliers The suppliers to match
50
* @param specialPropertyId This property id will always count as a match for the descriptor, regardless of
50
* @param specialPropertyId This property id will always count as a match for the descriptor, regardless of
51
* whether the node has this property or not
51
* whether the node has this property or not
52+
* @param existingPropertyIds sorted array of property ids for the entity to match schema for.
52
* @param callback The action to take on match
53
* @param callback The action to take on match
53
* @throws EXCEPTION This exception is propagated from the action
54
* @throws EXCEPTION This exception is propagated from the action
54
*/
55
*/
@@ -79,12 +80,12 @@ static <SUPPLIER extends SchemaDescriptorSupplier, EXCEPTION extends Exception>
79
* To avoid unnecessary store lookups, this implementation only gets propertyKeyIds for the node if some
80
* To avoid unnecessary store lookups, this implementation only gets propertyKeyIds for the node if some
80
* descriptor has a valid label.
81
* descriptor has a valid label.
81
*
82
*
82-
*
83
* @param <SUPPLIER> the type to match. Must implement SchemaDescriptorSupplier
83
* @param <SUPPLIER> the type to match. Must implement SchemaDescriptorSupplier
84
* @param <EXCEPTION> The type of exception that can be thrown when taking the action
84
* @param <EXCEPTION> The type of exception that can be thrown when taking the action
85
* @param schemaSuppliers The suppliers to match
85
* @param schemaSuppliers The suppliers to match
86
* @param specialPropertyId This property id will always count as a match for the descriptor, regardless of
86
* @param specialPropertyId This property id will always count as a match for the descriptor, regardless of
87
* whether the node has this property or not
87
* whether the node has this property or not
88+
* @param existingPropertyIds sorted array of property ids for the entity to match schema for.
88
* @param callback The action to take on match
89
* @param callback The action to take on match
89
* @throws EXCEPTION This exception is propagated from the action
90
* @throws EXCEPTION This exception is propagated from the action
90
*/
91
*/

community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/command/Command.java

Lines changed: 9 additions & 1 deletion
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -382,7 +382,15 @@ public boolean handle( CommandVisitor handler ) throws IOException
382

382

383
public long getEntityId()
383
public long getEntityId()
384
{
384
{
385-
return after.isNodeSet() ? after.getNodeId() : after.getRelId();
385+
if ( after.isNodeSet() )
386+
{
387+
return after.getNodeId();
388+
}
389+
if ( after.isRelSet() )
390+
{
391+
return after.getRelId();
392+
}
393+
throw new UnsupportedOperationException( format( "Unexpected owner of property %s, neither a node nor a relationship", after ) );
386
}
394
}
387

395

388
public long getNodeId()
396
public long getNodeId()

community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/SchemaDescriptorLookupSetTest.java

Lines changed: 114 additions & 33 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -21,8 +21,11 @@
21

21

22
import org.eclipse.collections.api.set.primitive.MutableIntSet;
22
import org.eclipse.collections.api.set.primitive.MutableIntSet;
23
import org.eclipse.collections.impl.factory.primitive.IntSets;
23
import org.eclipse.collections.impl.factory.primitive.IntSets;
24-
import org.junit.Rule;
24+
import org.junit.jupiter.api.Test;
25-
import org.junit.Test;
25+
import org.junit.jupiter.api.extension.ExtendWith;
26+
import org.junit.jupiter.params.ParameterizedTest;
27+
import org.junit.jupiter.params.provider.EnumSource;
28+
import org.junit.jupiter.params.provider.MethodSource;
26

29

27
import java.util.ArrayList;
30
import java.util.ArrayList;
28
import java.util.Arrays;
31
import java.util.Arrays;
@@ -34,9 +37,11 @@
34

37

35
import org.neo4j.helpers.collection.Iterators;
38
import org.neo4j.helpers.collection.Iterators;
36
import org.neo4j.internal.kernel.api.schema.SchemaDescriptor;
39
import org.neo4j.internal.kernel.api.schema.SchemaDescriptor;
37-
import org.neo4j.kernel.api.schema.LabelSchemaDescriptor;
40+
import org.neo4j.kernel.api.schema.MultiTokenSchemaDescriptor;
38
import org.neo4j.kernel.api.schema.SchemaDescriptorFactory;
41
import org.neo4j.kernel.api.schema.SchemaDescriptorFactory;
39
import org.neo4j.storageengine.api.EntityType;
42
import org.neo4j.storageengine.api.EntityType;
43+
import org.neo4j.test.extension.Inject;
44+
import org.neo4j.test.extension.RandomExtension;
40
import org.neo4j.test.rule.RandomRule;
45
import org.neo4j.test.rule.RandomRule;
41

46

42
import static java.util.Arrays.stream;
47
import static java.util.Arrays.stream;
@@ -45,75 +50,80 @@
45
import static org.neo4j.helpers.collection.Iterators.asSet;
50
import static org.neo4j.helpers.collection.Iterators.asSet;
46
import static org.neo4j.internal.kernel.api.schema.SchemaDescriptor.PropertySchemaType.COMPLETE_ALL_TOKENS;
51
import static org.neo4j.internal.kernel.api.schema.SchemaDescriptor.PropertySchemaType.COMPLETE_ALL_TOKENS;
47

52

48-
public class SchemaDescriptorLookupSetTest
53+
@ExtendWith( RandomExtension.class )
54+
class SchemaDescriptorLookupSetTest
49
{
55
{
50-
@Rule
56+
@Inject
51-
public final RandomRule random = new RandomRule();
57+
private RandomRule random;
52

58

53-
@Test
59+
@ParameterizedTest
54-
public void shouldLookupSingleKeyDescriptors()
60+
@EnumSource( DescriptorFactory.class )
61+
void shouldLookupSingleKeyDescriptors( DescriptorFactory factory )
55
{
62
{
56
// given
63
// given
57
SchemaDescriptorLookupSet<SchemaDescriptor> set = new SchemaDescriptorLookupSet<>();
64
SchemaDescriptorLookupSet<SchemaDescriptor> set = new SchemaDescriptorLookupSet<>();
58-
LabelSchemaDescriptor expected = SchemaDescriptorFactory.forLabel( 1, 2 );
65+
SchemaDescriptor expected = factory.descriptor( 1, 2 );
59
set.add( expected );
66
set.add( expected );
60

67

61
// when
68
// when
62
Set<SchemaDescriptor> descriptors = new HashSet<>();
69
Set<SchemaDescriptor> descriptors = new HashSet<>();
63-
set.matchingDescriptorsForPartialListOfProperties( descriptors, entityTokens( 1 ), properties( 2 ) );
70+
set.matchingDescriptorsForPartialListOfProperties( descriptors, longs( 1 ), ints( 2 ) );
64

71

65
// then
72
// then
66
assertEquals( asSet( expected ), descriptors );
73
assertEquals( asSet( expected ), descriptors );
67
}
74
}
68

75

69-
@Test
76+
@ParameterizedTest
70-
public void shouldLookupSingleKeyAndSharedCompositeKeyDescriptors()
77+
@EnumSource( DescriptorFactory.class )
78+
void shouldLookupSingleKeyAndSharedCompositeKeyDescriptors( DescriptorFactory factory )
71
{
79
{
72
// given
80
// given
73
SchemaDescriptorLookupSet<SchemaDescriptor> set = new SchemaDescriptorLookupSet<>();
81
SchemaDescriptorLookupSet<SchemaDescriptor> set = new SchemaDescriptorLookupSet<>();
74-
LabelSchemaDescriptor expected1 = SchemaDescriptorFactory.forLabel( 1, 2 );
82+
SchemaDescriptor expected1 = factory.descriptor( 1, 2 );
75-
LabelSchemaDescriptor expected2 = SchemaDescriptorFactory.forLabel( 1, 2, 3 );
83+
SchemaDescriptor expected2 = factory.descriptor( 1, 2, 3 );
76
set.add( expected1 );
84
set.add( expected1 );
77
set.add( expected2 );
85
set.add( expected2 );
78

86

79
// when
87
// when
80
Set<SchemaDescriptor> descriptors = new HashSet<>();
88
Set<SchemaDescriptor> descriptors = new HashSet<>();
81-
set.matchingDescriptorsForPartialListOfProperties( descriptors, entityTokens( 1 ), properties( 2 ) );
89+
set.matchingDescriptorsForPartialListOfProperties( descriptors, longs( 1 ), ints( 2 ) );
82

90

83
// then
91
// then
84
assertEquals( asSet( expected1, expected2 ), descriptors );
92
assertEquals( asSet( expected1, expected2 ), descriptors );
85
}
93
}
86

94

87-
@Test
95+
@ParameterizedTest
88-
public void shouldLookupCompositeKeyDescriptor()
96+
@EnumSource( DescriptorFactory.class )
97+
void shouldLookupCompositeKeyDescriptor( DescriptorFactory factory )
89
{
98
{
90
// given
99
// given
91
SchemaDescriptorLookupSet<SchemaDescriptor> set = new SchemaDescriptorLookupSet<>();
100
SchemaDescriptorLookupSet<SchemaDescriptor> set = new SchemaDescriptorLookupSet<>();
92-
LabelSchemaDescriptor descriptor1 = SchemaDescriptorFactory.forLabel( 1, 2, 3 );
101+
SchemaDescriptor descriptor1 = factory.descriptor( 1, 2, 3 );
93-
LabelSchemaDescriptor descriptor2 = SchemaDescriptorFactory.forLabel( 1, 2, 4 );
102+
SchemaDescriptor descriptor2 = factory.descriptor( 1, 2, 4 );
94-
LabelSchemaDescriptor descriptor3 = SchemaDescriptorFactory.forLabel( 1, 2, 5, 6 );
103+
SchemaDescriptor descriptor3 = factory.descriptor( 1, 2, 5, 6 );
95
set.add( descriptor1 );
104
set.add( descriptor1 );
96
set.add( descriptor2 );
105
set.add( descriptor2 );
97
set.add( descriptor3 );
106
set.add( descriptor3 );
98

107

99
// when
108
// when
100
Set<SchemaDescriptor> descriptors = new HashSet<>();
109
Set<SchemaDescriptor> descriptors = new HashSet<>();
101-
set.matchingDescriptorsForCompleteListOfProperties( descriptors, entityTokens( 1 ), properties( 2, 5, 6 ) );
110+
set.matchingDescriptorsForCompleteListOfProperties( descriptors, longs( 1 ), ints( 2, 5, 6 ) );
102

111

103
// then
112
// then
104
assertEquals( asSet( descriptor3 ), descriptors );
113
assertEquals( asSet( descriptor3 ), descriptors );
105
}
114
}
106

115

107-
@Test
116+
@ParameterizedTest
108-
public void shouldLookupAllByEntityToken()
117+
@EnumSource( DescriptorFactory.class )
118+
void shouldLookupAllByEntityToken( DescriptorFactory factory )
109
{
119
{
110
// given
120
// given
111
SchemaDescriptorLookupSet<SchemaDescriptor> set = new SchemaDescriptorLookupSet<>();
121
SchemaDescriptorLookupSet<SchemaDescriptor> set = new SchemaDescriptorLookupSet<>();
112-
LabelSchemaDescriptor descriptor1 = SchemaDescriptorFactory.forLabel( 1, 2, 3 );
122+
SchemaDescriptor descriptor1 = factory.descriptor( 1, 2, 3 );
113-
LabelSchemaDescriptor descriptor2 = SchemaDescriptorFactory.forLabel( 1, 2, 4 );
123+
SchemaDescriptor descriptor2 = factory.descriptor( 1, 2, 4 );
114-
LabelSchemaDescriptor descriptor3 = SchemaDescriptorFactory.forLabel( 1, 2, 5, 6 );
124+
SchemaDescriptor descriptor3 = factory.descriptor( 1, 2, 5, 6 );
115-
LabelSchemaDescriptor descriptor4 = SchemaDescriptorFactory.forLabel( 2, 2, 3 );
125+
SchemaDescriptor descriptor4 = factory.descriptor( 2, 2, 3 );
116-
LabelSchemaDescriptor descriptor5 = SchemaDescriptorFactory.forLabel( 3, 2, 5, 6 );
126+
SchemaDescriptor descriptor5 = factory.descriptor( 3, 2, 5, 6 );
117
set.add( descriptor1 );
127
set.add( descriptor1 );
118
set.add( descriptor2 );
128
set.add( descriptor2 );
119
set.add( descriptor3 );
129
set.add( descriptor3 );
@@ -122,20 +132,63 @@ public void shouldLookupAllByEntityToken()
122

132

123
// when
133
// when
124
Set<SchemaDescriptor> descriptors = new HashSet<>();
134
Set<SchemaDescriptor> descriptors = new HashSet<>();
125-
set.matchingDescriptors( descriptors, entityTokens( 1 ) );
135+
set.matchingDescriptors( descriptors, longs( 1 ) );
126

136

127
// then
137
// then
128
assertEquals( asSet( descriptor1, descriptor2, descriptor3 ), descriptors );
138
assertEquals( asSet( descriptor1, descriptor2, descriptor3 ), descriptors );
129
}
139
}
130

140

141+
@ParameterizedTest
142+
@MethodSource( "nodeAndRelationshipEntityTypes" )
143+
void shouldMatchOnAnyEntityAndPropertyTokenForPartialPropertySchemaType( EntityType entityType )
144+
{
145+
// given
146+
SchemaDescriptorLookupSet<SchemaDescriptor> set = new SchemaDescriptorLookupSet<>();
147+
MultiTokenSchemaDescriptor descriptor1 = SchemaDescriptorFactory.multiToken( ints( 0, 1, 2 ), entityType, 3, 4, 5 );
148+
MultiTokenSchemaDescriptor descriptor2 = SchemaDescriptorFactory.multiToken( ints( 0, 1 ), entityType, 3, 4 );
149+
MultiTokenSchemaDescriptor descriptor3 = SchemaDescriptorFactory.multiToken( ints( 0, 2 ), entityType, 4, 5 );
150+
set.add( descriptor1 );
151+
set.add( descriptor2 );
152+
set.add( descriptor3 );
153+
154+
// given that this test revolves around entity tokens 0,1,2 and property tokens 3,4,5 these 3 descriptors below matches either
155+
// only those tokens for entity or property or neither. I.e. these should never be included in matching results
156+
set.add( SchemaDescriptorFactory.multiToken( ints( 3, 4 ), entityType, 4, 5 ) );
157+
set.add( SchemaDescriptorFactory.multiToken( ints( 0, 1 ), entityType, 6, 7 ) );
158+
set.add( SchemaDescriptorFactory.multiToken( ints( 3, 4 ), entityType, 6, 7 ) );
159+
160+
// when matching these descriptors (in this case partial/complete list doesn't quite matter because the descriptors
161+
// themselves are partially matched anyway.
162+
Set<SchemaDescriptor> descriptors1 = new HashSet<>();
163+
Set<SchemaDescriptor> descriptors1Partial = new HashSet<>();
164+
Set<SchemaDescriptor> descriptors2 = new HashSet<>();
165+
Set<SchemaDescriptor> descriptors2Partial = new HashSet<>();
166+
Set<SchemaDescriptor> descriptors3 = new HashSet<>();
167+
Set<SchemaDescriptor> descriptors3Partial = new HashSet<>();
168+
set.matchingDescriptorsForCompleteListOfProperties( descriptors1, longs( 0, 1 ), ints( 4, 5 ) );
169+
set.matchingDescriptorsForPartialListOfProperties( descriptors1Partial, longs( 0, 1 ), ints( 4, 5 ) );
170+
set.matchingDescriptorsForCompleteListOfProperties( descriptors2, longs( 0 ), ints( 3 ) );
171+
set.matchingDescriptorsForPartialListOfProperties( descriptors2Partial, longs( 0 ), ints( 3 ) );
172+
set.matchingDescriptorsForCompleteListOfProperties( descriptors3, longs( 1 ), ints( 5 ) );
173+
set.matchingDescriptorsForPartialListOfProperties( descriptors3Partial, longs( 1 ), ints( 5 ) );
174+
175+
// then
176+
assertEquals( asSet( descriptor1, descriptor2, descriptor3 ), descriptors1 );
177+
assertEquals( asSet( descriptor1, descriptor2, descriptor3 ), descriptors1Partial );
178+
assertEquals( asSet( descriptor1, descriptor2 ), descriptors2 );
179+
assertEquals( asSet( descriptor1, descriptor2 ), descriptors2Partial );
180+
assertEquals( asSet( descriptor1 ), descriptors3 );
181+
assertEquals( asSet( descriptor1 ), descriptors3Partial );
182+
}
183+
131
@Test
184
@Test
132-
public void shouldAddRemoveAndLookupRandomDescriptorsNoIdempotentOperations()
185+
void shouldAddRemoveAndLookupRandomDescriptorsNoIdempotentOperations()
133
{
186
{
134
shouldAddRemoveAndLookupRandomDescriptors( false );
187
shouldAddRemoveAndLookupRandomDescriptors( false );
135
}
188
}
136

189

137
@Test
190
@Test
138-
public void shouldAddRemoveAndLookupRandomDescriptorsWithIdempotentOperations()
191+
void shouldAddRemoveAndLookupRandomDescriptorsWithIdempotentOperations()
139
{
192
{
140
shouldAddRemoveAndLookupRandomDescriptors( true );
193
shouldAddRemoveAndLookupRandomDescriptors( true );
141
}
194
}
@@ -287,13 +340,41 @@ private static long[] toLongArray( int[] array )
287
return result;
340
return result;
288
}
341
}
289

342

290-
private static int[] properties( int... properties )
343+
private static int[] ints( int... properties )
291
{
344
{
292
return properties;
345
return properties;
293
}
346
}
294

347

295-
private static long[] entityTokens( long... labels )
348+
private static long[] longs( long... labels )
296
{
349
{
297
return labels;
350
return labels;
298
}
351
}
352+
353+
private static EntityType[] nodeAndRelationshipEntityTypes()
354+
{
355+
return new EntityType[]{EntityType.NODE, EntityType.RELATIONSHIP};
356+
}
357+
358+
enum DescriptorFactory
359+
{
360+
NODE
361+
{
362+
@Override
363+
SchemaDescriptor descriptor( int labelId, int... propertyKeyIds )
364+
{
365+
return SchemaDescriptorFactory.forLabel( labelId, propertyKeyIds );
366+
}
367+
},
368+
RELATIONSHIP
369+
{
370+
@Override
371+
SchemaDescriptor descriptor( int relTypeId, int... propertyKeyIds )
372+
{
373+
return SchemaDescriptorFactory.forRelType( relTypeId, propertyKeyIds );
374+
}
375+
},
376+
;
377+
378+
abstract SchemaDescriptor descriptor( int entityTokenId, int... propertyKeyIds );
379+
}
299
}
380
}

0 commit comments

Comments
 (0)