5050import org .neo4j .values .virtual .MapValue ;
5151
5252import java .util .ArrayList ;
53+ import java .util .Collection ;
5354import java .util .HashSet ;
5455import java .util .List ;
5556import java .util .Map ;
5859import java .util .concurrent .atomic .LongAdder ;
5960import java .util .function .Function ;
6061import java .util .function .LongPredicate ;
62+ import java .util .function .Supplier ;
6163import java .util .stream .Collectors ;
6264
6365import static java .util .stream .Collectors .toMap ;
@@ -81,13 +83,11 @@ public final class NodesBuilder {
8183
8284 private final ConcurrentMap <String , NodePropertiesFromStoreBuilder > propertyBuildersByPropertyKey ;
8385
84- private final NodeLabelTokenToPropertyKeys nodeLabelTokenToPropertyKeys ;
85-
8686 NodesBuilder (
8787 long maxOriginalId ,
8888 int concurrency ,
8989 TokenToNodeLabel tokenToNodeLabel ,
90- NodeLabelTokenToPropertyKeys nodeLabelTokenToPropertyKeys ,
90+ Supplier < NodeLabelTokenToPropertyKeys > nodeLabelTokenToPropertyKeysSupplier ,
9191 ConcurrentMap <String , NodePropertiesFromStoreBuilder > propertyBuildersByPropertyKey ,
9292 IdMapBuilder idMapBuilder ,
9393 boolean hasLabelInformation ,
@@ -97,7 +97,6 @@ public final class NodesBuilder {
9797 ) {
9898 this .maxOriginalId = maxOriginalId ;
9999 this .concurrency = concurrency ;
100- this .nodeLabelTokenToPropertyKeys = nodeLabelTokenToPropertyKeys ;
101100 this .idMapBuilder = idMapBuilder ;
102101 this .propertyStates = propertyStates ;
103102 this .labelInformationBuilder = !hasLabelInformation
@@ -128,7 +127,7 @@ public final class NodesBuilder {
128127 hasLabelInformation ,
129128 hasProperties ,
130129 tokenToNodeLabel ,
131- nodeLabelTokenToPropertyKeys ,
130+ nodeLabelTokenToPropertyKeysSupplier . get () ,
132131 propertyBuilderFn
133132 )
134133 );
@@ -202,12 +201,15 @@ public Nodes build() {
202201 public Nodes build (long highestNeoId ) {
203202 // Flush remaining buffer contents
204203 this .threadLocalBuilder .forEach (ThreadLocalBuilder ::flush );
204+ // Collect token to property keys for final merge
205+ var nodeLabelTokenToPropertyKeysList = new ArrayList <NodeLabelTokenToPropertyKeys >();
206+ this .threadLocalBuilder .forEach (tlb -> nodeLabelTokenToPropertyKeysList .add (tlb .nodeLabelTokenToPropertyKeys ));
205207 // Clean up resources held by local builders
206208 this .threadLocalBuilder .close ();
207209
208210 var idMap = this .idMapBuilder .build (labelInformationBuilder , highestNeoId , concurrency );
209211 var nodeProperties = buildProperties (idMap );
210- var nodeSchema = buildNodeSchema (idMap , nodeProperties );
212+ var nodeSchema = buildNodeSchema (idMap , nodeLabelTokenToPropertyKeysList , nodeProperties );
211213 var nodePropertyStore = NodePropertyStore .builder ().properties (nodeProperties ).build ();
212214
213215 return ImmutableNodes .builder ()
@@ -217,7 +219,11 @@ public Nodes build(long highestNeoId) {
217219 .build ();
218220 }
219221
220- private NodeSchema buildNodeSchema (IdMap idMap , Map <String , NodeProperty > nodeProperties ) {
222+ private NodeSchema buildNodeSchema (
223+ IdMap idMap ,
224+ Collection <NodeLabelTokenToPropertyKeys > localNodeLabelTokenToPropertyKeys ,
225+ Map <String , NodeProperty > nodeProperties
226+ ) {
221227 var nodeSchema = NodeSchema .empty ();
222228 var importPropertySchemas = nodeProperties
223229 .entrySet ()
@@ -227,12 +233,19 @@ private NodeSchema buildNodeSchema(IdMap idMap, Map<String, NodeProperty> nodePr
227233 // consider node labels without properties
228234 var nodeLabels = new HashSet <>(idMap .availableNodeLabels ());
229235 // and also node labels with associated properties
230- nodeLabels .addAll (nodeLabelTokenToPropertyKeys .nodeLabels ());
231-
236+ localNodeLabelTokenToPropertyKeys .forEach (mapping -> nodeLabels .addAll (mapping .nodeLabels ()));
237+ // merge into a global mapping
238+ var globalNodeLabelTokenToPropertyKeys = localNodeLabelTokenToPropertyKeys
239+ .stream ()
240+ .reduce (
241+ NodeLabelTokenToPropertyKeys .lazy (),
242+ (left , right ) -> NodeLabelTokenToPropertyKeys .merge (left , right , importPropertySchemas )
243+ );
244+ // and construct final node property schema
232245 nodeLabels .forEach (nodeLabel -> {
233246 nodeSchema .addLabel (
234247 nodeLabel ,
235- this . nodeLabelTokenToPropertyKeys .propertySchemas (nodeLabel , importPropertySchemas )
248+ globalNodeLabelTokenToPropertyKeys .propertySchemas (nodeLabel , importPropertySchemas )
236249 );
237250 });
238251
@@ -331,6 +344,10 @@ private static class ThreadLocalBuilder implements AutoCloseable {
331344 this .batchNodeProperties = new ArrayList <>(buffer .capacity ());
332345 }
333346
347+ NodeLabelTokenToPropertyKeys nodeLabelTokenToPropertyKeys () {
348+ return this .nodeLabelTokenToPropertyKeys ;
349+ }
350+
334351 public void addNode (long originalId , NodeLabelToken nodeLabels ) {
335352 if (!seenNodeIdPredicate .test (originalId )) {
336353 long [] labels = getOrCreateLabelTokens (nodeLabels );
0 commit comments