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.
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
import org.neo4j.values.ValueWriter;
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>
{
/**
* <pre>
* 0: high bits ( 1 byte)
* 1: next ( 4 bytes)
* 5: prev ( 4 bytes)
* 1: next ( 4 bytes) where new property records are added
* 5: prev ( 4 bytes) points to more PropertyRecords in this chain
* 9: payload (32 bytes - 4 x 8 byte blocks)
* </pre>
* <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;
}

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

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

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 ) )
long next = prevPropertyRecordReference();
block = -1;
if ( next == NO_PROPERTIES )
{
if ( moreBlocksInRecord() )
{
return 2;
}
else
{
throw new UnsupportedOperationException( "not implemented" ); // long bytes in next record
}
close();
return false;
}
return 1;
return gotoVirtualAddress( next );
}

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

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

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

@Override
protected int dataBound()
private int blocksUsedByCurrent()
{
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 );
block = -1;
return combineReference( unsignedInt( 1 ), ((long) unsignedByte( 0 ) & 0x0FL) << 32 );
}

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

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

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

@ClassRule
public static final GraphSetup graph = new GraphSetup()
Expand All @@ -60,6 +63,22 @@ protected void create( GraphDatabaseService graphDb )
trueProp = createNodeWithProperty( graphDb, "trueProp", true );
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();
}
}
Expand Down Expand Up @@ -96,7 +115,7 @@ public void shouldNotAccessNonExistentProperties() throws Exception
}

@Test
public void shouldAccessIntProperty() throws Exception
public void shouldAccessSingleProperty() throws Exception
{
assertAccessSingleProperty( byteProp, (byte)13 );
assertAccessSingleProperty( shortProp, (short)13 );
Expand All @@ -109,6 +128,37 @@ public void shouldAccessIntProperty() throws Exception
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 )
{
// given
Expand Down

0 comments on commit d6824d3

Please sign in to comment.