@@ -199,17 +199,11 @@ public Nodes build() {
199199 }
200200
201201 public Nodes build (long highestNeoId ) {
202- // Flush remaining buffer contents
203- 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 ));
207- // Clean up resources held by local builders
208- this .threadLocalBuilder .close ();
202+ var localLabelTokenToPropertyKeys = closeThreadLocalBuilders ();
209203
210204 var idMap = this .idMapBuilder .build (labelInformationBuilder , highestNeoId , concurrency );
211205 var nodeProperties = buildProperties (idMap );
212- var nodeSchema = buildNodeSchema (idMap , nodeLabelTokenToPropertyKeysList , nodeProperties );
206+ var nodeSchema = buildNodeSchema (idMap , localLabelTokenToPropertyKeys , nodeProperties );
213207 var nodePropertyStore = NodePropertyStore .builder ().properties (nodeProperties ).build ();
214208
215209 return ImmutableNodes .builder ()
@@ -219,37 +213,53 @@ public Nodes build(long highestNeoId) {
219213 .build ();
220214 }
221215
216+ private List <NodeLabelTokenToPropertyKeys > closeThreadLocalBuilders () {
217+ // Flush remaining buffer contents
218+ this .threadLocalBuilder .forEach (ThreadLocalBuilder ::flush );
219+ // Collect token to property keys for final union
220+ var labelTokenToPropertyKeys = new ArrayList <NodeLabelTokenToPropertyKeys >();
221+ this .threadLocalBuilder .forEach (tlb -> labelTokenToPropertyKeys .add (tlb .nodeLabelTokenToPropertyKeys ));
222+ // Clean up resources held by local builders
223+ this .threadLocalBuilder .close ();
224+
225+ return labelTokenToPropertyKeys ;
226+ }
227+
222228 private NodeSchema buildNodeSchema (
223229 IdMap idMap ,
224- Collection <NodeLabelTokenToPropertyKeys > localNodeLabelTokenToPropertyKeys ,
230+ Collection <NodeLabelTokenToPropertyKeys > localLabelTokenToPropertyKeys ,
225231 Map <String , NodeProperty > nodeProperties
226232 ) {
227- var nodeSchema = NodeSchema .empty ();
228- var importPropertySchemas = nodeProperties
233+
234+ // Collect the property schemas from the imported property values.
235+ var propertyKeysToSchema = nodeProperties
229236 .entrySet ()
230237 .stream ()
231238 .collect (Collectors .toMap (Map .Entry ::getKey , entry -> entry .getValue ().propertySchema ()));
232-
233- // consider node labels without properties
234- var nodeLabels = new HashSet <>(idMap .availableNodeLabels ());
235- // and also node labels with associated properties
236- localNodeLabelTokenToPropertyKeys .forEach (mapping -> nodeLabels .addAll (mapping .nodeLabels ()));
237- // merge into a global mapping
238- var globalNodeLabelTokenToPropertyKeys = localNodeLabelTokenToPropertyKeys
239+ // Union the label to property key mappings from each import thread.
240+ var globalLabelTokenToPropertyKeys = localLabelTokenToPropertyKeys
239241 .stream ()
240242 .reduce (
241243 NodeLabelTokenToPropertyKeys .lazy (),
242- (left , right ) -> NodeLabelTokenToPropertyKeys .merge (left , right , importPropertySchemas )
243- );
244- // and construct final node property schema
245- nodeLabels .forEach (nodeLabel -> {
246- nodeSchema .addLabel (
247- nodeLabel ,
248- globalNodeLabelTokenToPropertyKeys .propertySchemas (nodeLabel , importPropertySchemas )
244+ (left , right ) -> NodeLabelTokenToPropertyKeys .union (left , right , propertyKeysToSchema )
249245 );
250- });
246+ // Collect node labels without properties from the id map
247+ // as they are not stored in the above union mapping.
248+ var nodeLabels = new HashSet <>(idMap .availableNodeLabels ());
249+ // Add labels that actually have node properties attached.
250+ localLabelTokenToPropertyKeys .forEach (localMapping -> nodeLabels .addAll (localMapping .nodeLabels ()));
251251
252- return nodeSchema ;
252+ // Use all labels and the global label to property
253+ // key mapping to construct the final node schema.
254+ return nodeLabels .stream ()
255+ .reduce (
256+ NodeSchema .empty (),
257+ (unionSchema , nodeLabel ) -> unionSchema .addLabel (
258+ nodeLabel ,
259+ globalLabelTokenToPropertyKeys .propertySchemas (nodeLabel , propertyKeysToSchema )
260+ ),
261+ (lhs , rhs ) -> lhs
262+ );
253263 }
254264
255265 private Map <String , NodeProperty > buildProperties (IdMap idMap ) {
@@ -344,10 +354,6 @@ private static class ThreadLocalBuilder implements AutoCloseable {
344354 this .batchNodeProperties = new ArrayList <>(buffer .capacity ());
345355 }
346356
347- NodeLabelTokenToPropertyKeys nodeLabelTokenToPropertyKeys () {
348- return this .nodeLabelTokenToPropertyKeys ;
349- }
350-
351357 public void addNode (long originalId , NodeLabelToken nodeLabels ) {
352358 if (!seenNodeIdPredicate .test (originalId )) {
353359 long [] labels = getOrCreateLabelTokens (nodeLabels );
0 commit comments