private static int getMaxSupportedDimensions() { return PropertyType.getPayloadSizeLongs() - 1; }
public void setValueBlocks( long[] blocks ) { int expectedPayloadSize = PropertyType.getPayloadSizeLongs(); assert blocks == null || blocks.length <= expectedPayloadSize : "I was given an array of size " + blocks.length + ", but I wanted it to be " + expectedPayloadSize; this.valueBlocks = blocks; if ( valueRecords != null ) { valueRecords.clear(); } }
@Override public String toString() { return super.toString() + "[blocksPerRecord:" + PropertyType.getPayloadSizeLongs() + "]"; }
/** * For property records there's no "inUse" byte and we need to read the whole record to * see if there are any PropertyBlocks in use in it. */ @Override public boolean isInUse( PageCursor cursor ) { cursor.setOffset( cursor.getOffset() /*skip...*/ + 1/*mod*/ + 4/*prev*/ + 4/*next*/ ); int blocks = PropertyType.getPayloadSizeLongs(); for ( int i = 0; i < blocks; i++ ) { long block = cursor.getLong(); // Since there's no inUse byte we have to check the special case of first block == 0, which will mean that it's deleted if ( i == 0 && block == 0 ) { return false; } if ( PropertyType.getPropertyTypeOrNull( block ) != null ) { return true; } } return false; } }
@Override public int applyAsInt( Value[] values ) { stringRecordIds.reset(); arrayRecordIds.reset(); int propertyRecordsUsed = 0; int freeBlocksInCurrentRecord = 0; for ( Value value : values ) { PropertyBlock block = new PropertyBlock(); PropertyStore.encodeValue( block, 0 /*doesn't matter*/, value, stringRecordCounter, arrayRecordCounter, true ); if ( block.getValueBlocks().length > freeBlocksInCurrentRecord ) { propertyRecordsUsed++; freeBlocksInCurrentRecord = PropertyType.getPayloadSizeLongs(); } freeBlocksInCurrentRecord -= block.getValueBlocks().length; } int size = propertyRecordsUsed * propertyRecordSize; size += toIntExact( stringRecordIds.peek() ) * stringRecordSize; size += toIntExact( arrayRecordIds.peek() ) * arrayRecordSize; return size; } }
if ( Bits.requiredLongs( numberOfBytes ) > PropertyType.getPayloadSizeLongs() )
@Test public void deleteAndAddToFullPropertyRecord() { // Fill it up, each integer is one block Node node = getGraphDb().createNode(); for ( int i = 0; i < PropertyType.getPayloadSizeLongs(); i++ ) { node.setProperty( "prop" + i, i ); } newTransaction(); // Remove all but one and add one for ( int i = 0; i < PropertyType.getPayloadSizeLongs() - 1; i++ ) { assertEquals( i, node.removeProperty( "prop" + i ) ); } node.setProperty( "profit", 5 ); newTransaction(); // Verify int remainingProperty = PropertyType.getPayloadSizeLongs() - 1; assertEquals( remainingProperty, node.getProperty( "prop" + remainingProperty ) ); assertEquals( 5, node.getProperty( "profit" ) ); }
@Test public void testChangePropertyType() { Node node = getGraphDb().createNode(); long recordsInUseAtStart = propertyRecordsInUse(); int stuffedShortStrings = 0; for ( ; stuffedShortStrings < PropertyType.getPayloadSizeLongs(); stuffedShortStrings++ ) { node.setProperty( "shortString" + stuffedShortStrings, String.valueOf( stuffedShortStrings ) ); } newTransaction(); assertEquals( recordsInUseAtStart + 1, propertyRecordsInUse() ); node.setProperty( "shortString1", 1.0 ); commit(); }
@Test public void simpleAddDoubles() { long inUseBefore = propertyRecordsInUse(); Node node = getGraphDb().createNode(); for ( int i = 0; i < PropertyType.getPayloadSizeLongs() / 2; i++ ) { node.setProperty( "prop" + i, i * -1.0 ); assertEquals( i * -1.0, node.getProperty( "prop" + i ) ); } newTransaction(); assertEquals( inUseBefore + 1, propertyRecordsInUse() ); for ( int i = 0; i < PropertyType.getPayloadSizeLongs() / 2; i++ ) { assertEquals( i * -1.0, node.getProperty( "prop" + i ) ); } for ( int i = 0; i < PropertyType.getPayloadSizeLongs() / 2; i++ ) { assertEquals( i * -1.0, node.removeProperty( "prop" + i ) ); assertFalse( node.hasProperty( "prop" + i ) ); } commit(); assertEquals( inUseBefore, propertyRecordsInUse() ); }
@Test public void simpleAddIntegers() { long inUseBefore = propertyRecordsInUse(); Node node = getGraphDb().createNode(); for ( int i = 0; i < PropertyType.getPayloadSizeLongs(); i++ ) { node.setProperty( "prop" + i, i ); assertEquals( i, node.getProperty( "prop" + i ) ); } newTransaction(); assertEquals( inUseBefore + 1, propertyRecordsInUse() ); for ( int i = 0; i < PropertyType.getPayloadSizeLongs(); i++ ) { assertEquals( i, node.getProperty( "prop" + i ) ); } for ( int i = 0; i < PropertyType.getPayloadSizeLongs(); i++ ) { assertEquals( i, node.removeProperty( "prop" + i ) ); assertFalse( node.hasProperty( "prop" + i ) ); } commit(); assertEquals( inUseBefore, propertyRecordsInUse() ); }
private void testYoyoArrayBase( boolean withNewTx ) { Relationship rel = getGraphDb().createNode().createRelationshipTo( getGraphDb().createNode(), RelationshipType.withName( "LOCKS" ) ); long recordsInUseAtStart = propertyRecordsInUse(); long valueRecordsInUseAtStart = dynamicArrayRecordsInUse(); List<Long> theYoyoData = new ArrayList<>(); for ( int i = 0; i < PropertyType.getPayloadSizeLongs() - 1; i++ ) { theYoyoData.add( 1L << 63 ); Long[] value = theYoyoData.toArray( new Long[] {} ); rel.setProperty( "yoyo", value ); if ( withNewTx ) { newTransaction(); assertEquals( recordsInUseAtStart + 1, propertyRecordsInUse() ); assertEquals( valueRecordsInUseAtStart, dynamicArrayRecordsInUse() ); } } theYoyoData.add( 1L << 63 ); Long[] value = theYoyoData.toArray( new Long[] {} ); rel.setProperty( "yoyo", value ); newTransaction(); assertEquals( recordsInUseAtStart + 1, propertyRecordsInUse() ); assertEquals( valueRecordsInUseAtStart + 1, dynamicArrayRecordsInUse() ); rel.setProperty( "filler", new long[] { 1L << 63, 1L << 63, 1L << 63 } ); newTransaction(); assertEquals( recordsInUseAtStart + 2, propertyRecordsInUse() ); }
for ( ; stuffedShortStrings < 3 * PropertyType.getPayloadSizeLongs(); stuffedShortStrings++ ) assertEquals( PropertyType.getPayloadSizeLongs() - 2, deletedProps );
@Test public void testBlockDefragmentationWithTwoSpaces() Assume.assumeTrue( PropertyType.getPayloadSizeLongs() > 2 ); Node node = getGraphDb().createNode(); long inUseBefore = propertyRecordsInUse(); for ( ; stuffedIntegers < PropertyType.getPayloadSizeLongs(); stuffedIntegers++ ) assertEquals( stuffedIntegers, PropertyType.getPayloadSizeLongs() ); newTransaction();
Node node = getGraphDb().createNode(); for ( int i = 0; i < 3 * PropertyType.getPayloadSizeLongs(); i++ )
@Test public void testAdditionHappensInTheMiddleIfItFits() { Node node = getGraphDb().createNode(); long recordsInUseAtStart = propertyRecordsInUse(); node.setProperty( "int1", 1 ); node.setProperty( "double1", 1.0 ); node.setProperty( "int2", 2 ); int stuffedShortStrings = 0; for ( ; stuffedShortStrings < PropertyType.getPayloadSizeLongs(); stuffedShortStrings++ ) { node.setProperty( "shortString" + stuffedShortStrings, String.valueOf( stuffedShortStrings ) ); } newTransaction(); assertEquals( recordsInUseAtStart + 2, propertyRecordsInUse() ); node.removeProperty( "shortString" + 1 ); node.setProperty( "int3", 3 ); newTransaction(); assertEquals( recordsInUseAtStart + 2, propertyRecordsInUse() ); }
if ( longsAppended < PropertyType.getPayloadSizeLongs() )
for ( int i = 0; i < PropertyType.getPayloadSizeLongs() / 2; i++ ) for ( int i = 0; i < PropertyType.getPayloadSizeLongs() % 2; i++ )
for ( ; stuffedShortStrings < PropertyType.getPayloadSizeLongs(); stuffedShortStrings++ )
@Test public void checkDeletesRemoveRecordsWhenProper() { Node node = getGraphDb().createNode(); long recordsInUseAtStart = propertyRecordsInUse(); int stuffedBooleans = 0; for ( ; stuffedBooleans < PropertyType.getPayloadSizeLongs(); stuffedBooleans++ ) { node.setProperty( "boolean" + stuffedBooleans, stuffedBooleans % 2 == 0 ); } newTransaction(); assertEquals( recordsInUseAtStart + 1, propertyRecordsInUse() ); node.setProperty( "theExraOne", true ); newTransaction(); assertEquals( recordsInUseAtStart + 2, propertyRecordsInUse() ); for ( int i = 0; i < stuffedBooleans; i++ ) { assertEquals( Boolean.valueOf( i % 2 == 0 ), node.removeProperty( "boolean" + i ) ); } newTransaction(); assertEquals( recordsInUseAtStart + 1, propertyRecordsInUse() ); for ( int i = 0; i < stuffedBooleans; i++ ) { assertFalse( node.hasProperty( "boolean" + i ) ); } assertEquals( Boolean.TRUE, node.getProperty( "theExraOne" ) ); }
for ( int i = 1; i < PropertyType.getPayloadSizeLongs(); i++ )