Skip to content

Commit

Permalink
Read multiple properties from single node
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Jun 25, 2017
1 parent b3ee473 commit d6824d3
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 36 deletions.
Expand Up @@ -24,13 +24,15 @@
import org.neo4j.values.ValueWriter; import org.neo4j.values.ValueWriter;
import org.neo4j.values.Values; import org.neo4j.values.Values;


import static org.neo4j.impl.store.prototype.neole.ReadStore.combineReference;

class PropertyCursor extends org.neo4j.impl.store.prototype.PropertyCursor<ReadStore> class PropertyCursor extends org.neo4j.impl.store.prototype.PropertyCursor<ReadStore>
{ {
/** /**
* <pre> * <pre>
* 0: high bits ( 1 byte) * 0: high bits ( 1 byte)
* 1: next ( 4 bytes) * 1: next ( 4 bytes) where new property records are added
* 5: prev ( 4 bytes) * 5: prev ( 4 bytes) points to more PropertyRecords in this chain
* 9: payload (32 bytes - 4 x 8 byte blocks) * 9: payload (32 bytes - 4 x 8 byte blocks)
* </pre> * </pre>
* <h2>high bits</h2> * <h2>high bits</h2>
Expand Down Expand Up @@ -95,6 +97,12 @@ class PropertyCursor extends org.neo4j.impl.store.prototype.PropertyCursor<ReadS
block = Integer.MIN_VALUE; block = Integer.MIN_VALUE;
} }


void init( StoreFile properties, long reference )
{
ReadStore.setup( properties, this, reference );
block = -1;
}

@Override @Override
public boolean next() public boolean next()
{ {
Expand All @@ -108,32 +116,14 @@ public boolean next()
} }
nextBlock = block + blocksUsedByCurrent(); nextBlock = block + blocksUsedByCurrent();
} }
// TODO: move to next record if needed long next = prevPropertyRecordReference();
close(); block = -1;
return false; if ( next == NO_PROPERTIES )
}

private int blocksUsedByCurrent()
{
if ( block == -1 )
{
return 1;
}
long valueBytes = block( this.block );
long typeId = (valueBytes & 0x0F00_0000L) >> 24;
if ( typeId == DOUBLE ||
(typeId == LONG && ( valueBytes & 0x0000_0000_1000_0000 ) == 0 ) )
{ {
if ( moreBlocksInRecord() ) close();
{ return false;
return 2;
}
else
{
throw new UnsupportedOperationException( "not implemented" ); // long bytes in next record
}
} }
return 1; return gotoVirtualAddress( next );
} }


@Override @Override
Expand Down Expand Up @@ -213,7 +203,7 @@ public Value propertyValue()
{ {
if ( moreBlocksInRecord() ) if ( moreBlocksInRecord() )
{ {
return block( this.block + 1 ); return Values.longValue( block( this.block + 1 ) );
} }
else else
{ {
Expand All @@ -225,7 +215,7 @@ public Value propertyValue()
return Values.floatValue( return Values.floatValue(
Float.intBitsToFloat((int)((block( this.block ) & 0x0FFF_FFFF_F000_0000L) >> 28) ) ); Float.intBitsToFloat((int)((block( this.block ) & 0x0FFF_FFFF_F000_0000L) >> 28) ) );
case DOUBLE: case DOUBLE:
return Double.longBitsToDouble( block( this.block + 1 ) ); return Values.doubleValue( Double.longBitsToDouble( block( this.block + 1 ) ) );
case STRING_REFERENCE: case STRING_REFERENCE:
throw new UnsupportedOperationException( "not implemented" ); throw new UnsupportedOperationException( "not implemented" );
case ARRAY_REFERENCE: case ARRAY_REFERENCE:
Expand All @@ -239,6 +229,12 @@ public Value propertyValue()
} }
} }


@Override
protected int dataBound()
{
return RECORD_SIZE;
}

private boolean moreBlocksInRecord() private boolean moreBlocksInRecord()
{ {
return block < 3; return block < 3;
Expand All @@ -250,15 +246,36 @@ public <E extends Exception> void writeTo( ValueWriter<E> target )
throw new UnsupportedOperationException( "not implemented" ); throw new UnsupportedOperationException( "not implemented" );
} }


@Override private int blocksUsedByCurrent()
protected int dataBound()
{ {
return RECORD_SIZE; if ( block == -1 )
{
return 1;
}
long valueBytes = block( this.block );
long typeId = (valueBytes & 0x1F00_0000L) >> 24;
if ( typeId == DOUBLE ||
(typeId == LONG && ( valueBytes & 0x0000_0000_1000_0000 ) == 0 ) )
{
if ( moreBlocksInRecord() )
{
return 2;
}
else
{
throw new UnsupportedOperationException( "not implemented" ); // long/double bytes in next record
}
}
return 1;
} }


void init( StoreFile properties, long reference ) private long nextPropertyRecordReference()
{ {
ReadStore.setup( properties, this, reference ); return combineReference( unsignedInt( 1 ), ((long) unsignedByte( 0 ) & 0x0FL) << 32 );
block = -1; }

private long prevPropertyRecordReference()
{
return combineReference( unsignedInt( 5 ), ((long) unsignedByte( 0 ) & 0xF0L) << 31 );
} }
} }
Expand Up @@ -22,6 +22,9 @@
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Test; import org.junit.Test;


import java.util.HashSet;
import java.util.Set;

import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.Transaction;
Expand All @@ -36,7 +39,7 @@
public class PropertyCursorTest public class PropertyCursorTest
{ {
private static long bare, byteProp, shortProp, intProp, inlineLongProp, longProp, private static long bare, byteProp, shortProp, intProp, inlineLongProp, longProp,
floatProp, doubleProp, trueProp, falseProp; floatProp, doubleProp, trueProp, falseProp, allProps;


@ClassRule @ClassRule
public static final GraphSetup graph = new GraphSetup() public static final GraphSetup graph = new GraphSetup()
Expand All @@ -60,6 +63,22 @@ protected void create( GraphDatabaseService graphDb )
trueProp = createNodeWithProperty( graphDb, "trueProp", true ); trueProp = createNodeWithProperty( graphDb, "trueProp", true );
falseProp = createNodeWithProperty( graphDb, "falseProp", false ); falseProp = createNodeWithProperty( graphDb, "falseProp", false );


Node all = graphDb.createNode();
// first property record
all.setProperty( "byteProp", (byte)13 );
all.setProperty( "shortProp", (short)13 );
all.setProperty( "intProp", 13 );
all.setProperty( "inlineLongProp", 13L );
// second property record
all.setProperty( "longProp", Long.MAX_VALUE );
all.setProperty( "floatProp", 13.0f );
all.setProperty( "doubleProp", 13.0 );
// ^^^
// third property record halfway through double?
all.setProperty( "trueProp", true );
all.setProperty( "falseProp", false );
allProps = all.getId();

tx.success(); tx.success();
} }
} }
Expand Down Expand Up @@ -96,7 +115,7 @@ public void shouldNotAccessNonExistentProperties() throws Exception
} }


@Test @Test
public void shouldAccessIntProperty() throws Exception public void shouldAccessSingleProperty() throws Exception
{ {
assertAccessSingleProperty( byteProp, (byte)13 ); assertAccessSingleProperty( byteProp, (byte)13 );
assertAccessSingleProperty( shortProp, (short)13 ); assertAccessSingleProperty( shortProp, (short)13 );
Expand All @@ -109,6 +128,37 @@ public void shouldAccessIntProperty() throws Exception
assertAccessSingleProperty( falseProp, false ); assertAccessSingleProperty( falseProp, false );
} }


@Test
public void shouldAccessAllNodeProperties() throws Exception
{
// given
try ( NodeCursor node = graph.allocateNodeCursor();
PropertyCursor props = graph.allocatePropertyCursor() )
{
// when
graph.singleNode( allProps, node );
assertTrue( "node by reference", node.next() );
assertTrue( "has properties", node.hasProperties() );

node.properties( props );
Set<Object> values = new HashSet<>();
while ( props.next() )
{
values.add( props.propertyValue() );
}

assertTrue( "byteProp", values.contains( (byte)13 ) );
assertTrue( "shortProp", values.contains( (short)13 ) );
assertTrue( "intProp", values.contains( 13 ) );
assertTrue( "inlineLongProp", values.contains( 13L ) );
assertTrue( "longProp", values.contains( Long.MAX_VALUE ) );
assertTrue( "floatProp", values.contains( 13.0f ) );
assertTrue( "doubleProp", values.contains( 13.0 ) );
assertTrue( "trueProp", values.contains( true ) );
assertTrue( "falseProp", values.contains( false ) );
}
}

private void assertAccessSingleProperty( long nodeId, Object expectedValue ) private void assertAccessSingleProperty( long nodeId, Object expectedValue )
{ {
// given // given
Expand Down

0 comments on commit d6824d3

Please sign in to comment.