private boolean nodeHasLabel( long node, int labelId ) { NodeRecord record = getNodeRecord( node ).forReadingData(); for ( long label : parseLabelsField( record ).get( nodeStore ) ) { if ( label == labelId ) { return true; } } return false; }
@Override public void ensureHeavy( NodeRecord node ) { if ( NodeLabelsField.fieldPointsToDynamicRecordOfLabels( node.getLabelField() ) ) { ensureHeavy( node, NodeLabelsField.firstDynamicLabelRecordId( node.getLabelField() ) ); } }
@Override public long[] labels() { return NodeLabelsField.get( this, read ); }
/** * @see NodeRecord * * @param labelField label field value from a node record * @return the id of the dynamic record this label field points to or null if it is an inline label field */ public static long firstDynamicLabelRecordId( long labelField ) { assert fieldPointsToDynamicRecordOfLabels( labelField ); return parseLabelsBody( labelField ); }
public long getFirstDynamicRecordId() { return firstDynamicLabelRecordId( node.getLabelField() ); }
private static boolean mayResultInIndexUpdates( NodeCommand command ) { long before = command.getBefore().getLabelField(); long after = command.getAfter().getLabelField(); return before != after || // Because we don't know here, there may have been changes to a dynamic label record // even though it still points to the same one fieldPointsToDynamicRecordOfLabels( before ) || fieldPointsToDynamicRecordOfLabels( after ); }
@Test public void shouldDedupLabelIds() { // GIVEN BatchingLabelTokenRepository repo = new BatchingLabelTokenRepository( mock( TokenStore.class ) ); // WHEN long[] ids = repo.getOrCreateIds( new String[] {"One", "Two", "One"} ); // THEN assertTrue( NodeLabelsField.isSane( ids ) ); }
public static long[] parseInlined( long labelField ) { byte numberOfLabels = labelCount( labelField ); if ( numberOfLabels == 0 ) { return EMPTY_LONG_ARRAY; } long existingLabelsField = parseLabelsBody( labelField ); byte bitsPerLabel = (byte) (LABEL_BITS / numberOfLabels); Bits bits = bitsFromLongs( new long[]{existingLabelsField} ); long[] result = new long[numberOfLabels]; for ( int i = 0; i < result.length; i++ ) { result[i] = bits.getLong( bitsPerLabel ); } return result; }
@Override public String toString() { if ( node.isLight() ) { return format( "Dynamic(id:%d)", firstDynamicLabelRecordId( node.getLabelField() ) ); } return format( "Dynamic(id:%d,[%s])", firstDynamicLabelRecordId( node.getLabelField() ), Arrays.toString( getDynamicLabelsArrayFromHeavyRecords( node.getUsedDynamicLabelRecords() ) ) ); }
public static long[] get( NodeRecord node, NodeStore nodeStore ) { return fieldPointsToDynamicRecordOfLabels( node.getLabelField() ) ? DynamicNodeLabels.get( node, nodeStore ) : InlineNodeLabels.get( node ); }
static Collection<DynamicRecord> putSorted( NodeRecord node, long[] labelIds, NodeStore nodeStore, DynamicRecordAllocator allocator ) { long existingLabelsField = node.getLabelField(); long existingLabelsBits = parseLabelsBody( existingLabelsField ); Collection<DynamicRecord> changedDynamicRecords = node.getDynamicLabelRecords(); long labelField = node.getLabelField(); if ( fieldPointsToDynamicRecordOfLabels( labelField ) ) { // There are existing dynamic label records, get them nodeStore.ensureHeavy( node, existingLabelsBits ); changedDynamicRecords = node.getDynamicLabelRecords(); setNotInUse( changedDynamicRecords ); } if ( !InlineNodeLabels.tryInlineInNodeRecord( node, labelIds, changedDynamicRecords ) ) { Iterator<DynamicRecord> recycledRecords = changedDynamicRecords.iterator(); Collection<DynamicRecord> allocatedRecords = allocateRecordsForDynamicLabels( node.getId(), labelIds, new ReusableRecordsCompositeAllocator( recycledRecords, allocator ) ); // Set the rest of the previously set dynamic records as !inUse while ( recycledRecords.hasNext() ) { DynamicRecord removedRecord = recycledRecords.next(); removedRecord.setInUse( false ); allocatedRecords.add( removedRecord ); } node.setLabelField( dynamicPointer( allocatedRecords ), allocatedRecords ); changedDynamicRecords = allocatedRecords; } return changedDynamicRecords; }
@Test public void shouldSortLabelIds() { // GIVEN BatchingLabelTokenRepository repo = new BatchingLabelTokenRepository( mock( TokenStore.class ) ); long[] expected = new long[] { repo.getOrCreateId( "One" ), repo.getOrCreateId( "Two" ), repo.getOrCreateId( "Three" ) }; // WHEN long[] ids = repo.getOrCreateIds( new String[] {"Two", "One", "Three"} ); // THEN assertArrayEquals( expected, ids ); assertTrue( NodeLabelsField.isSane( ids ) ); }
public static long[] parseInlined( long labelField ) { byte numberOfLabels = labelCount( labelField ); if ( numberOfLabels == 0 ) { return EMPTY_LONG_ARRAY; } long existingLabelsField = parseLabelsBody( labelField ); byte bitsPerLabel = (byte) (LABEL_BITS / numberOfLabels); Bits bits = bitsFromLongs( new long[]{existingLabelsField} ); long[] result = new long[numberOfLabels]; for ( int i = 0; i < result.length; i++ ) { result[i] = bits.getLong( bitsPerLabel ); } return result; }
private void setNodeLabels( NodeRecord nodeRecord, Label... labels ) { NodeLabels nodeLabels = parseLabelsField( nodeRecord ); nodeLabels.put( getOrCreateLabelIds( labels ), nodeStore, nodeStore.getDynamicLabelStore() ); labelsTouched = true; }
public static long[] getListOfLabels( NodeRecord nodeRecord, RecordStore<DynamicRecord> labels ) { long field = nodeRecord.getLabelField(); if ( NodeLabelsField.fieldPointsToDynamicRecordOfLabels( field ) ) { List<DynamicRecord> recordList = new ArrayList<>(); final MutableLongSet alreadySeen = new LongHashSet(); long id = NodeLabelsField.firstDynamicLabelRecordId( field ); while ( !Record.NULL_REFERENCE.is( id ) ) { DynamicRecord record = labels.getRecord( id, labels.newRecord(), FORCE ); if ( !record.inUse() || !alreadySeen.add( id ) ) { return PrimitiveLongCollections.EMPTY_LONG_ARRAY; } recordList.add( record ); } return LabelChainWalker.labelIds( recordList ); } return InlineNodeLabels.get( nodeRecord ); }
public static long[] get( NodeRecord node, NodeStore nodeStore ) { if ( node.isLight() ) { nodeStore.ensureHeavy( node, firstDynamicLabelRecordId( node.getLabelField() ) ); } return getDynamicLabelsArray( node.getUsedDynamicLabelRecords(), nodeStore.getDynamicLabelStore() ); }
public static NodeLabels parseLabelsField( NodeRecord node ) { long labelField = node.getLabelField(); return fieldPointsToDynamicRecordOfLabels( labelField ) ? new DynamicNodeLabels( node ) : new InlineNodeLabels( node ); }
/** * @see NodeRecord * * @param labelField label field value from a node record * @return the id of the dynamic record this label field points to or null if it is an inline label field */ public static long firstDynamicLabelRecordId( long labelField ) { assert fieldPointsToDynamicRecordOfLabels( labelField ); return parseLabelsBody( labelField ); }
@Override public boolean hasLabel( int label ) { //Get labels from store and put in intSet, unfortunately we get longs back long[] longs = NodeLabelsField.get( this, read ); for ( long labelToken : longs ) { if ( labelToken == label ) { assert (int) labelToken == labelToken : "value too big to be represented as and int"; return true; } } return false; }
@Override public String toString() { String denseInfo = (dense ? "group" : "rel") + "=" + nextRel; String lightHeavyInfo = isLight ? "light" : dynamicLabelRecords.isEmpty() ? "heavy" : "heavy,dynlabels=" + dynamicLabelRecords; return "Node[" + getId() + ",used=" + inUse() + "," + denseInfo + ",prop=" + getNextProp() + ",labels=" + parseLabelsField( this ) + "," + lightHeavyInfo + ",secondaryUnitId=" + getSecondaryUnitId() + "]"; }