Skip to content

Adding missing profile statistics #642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,30 @@

import java.util.List;
import java.util.Map;
import java.util.function.Function;

import org.neo4j.driver.Value;
import org.neo4j.driver.summary.ProfiledPlan;
import java.util.function.Function;

public class InternalProfiledPlan extends InternalPlan<ProfiledPlan> implements ProfiledPlan
{
private final long dbHits;
private final long records;
private final long pageCacheHits;
private final long pageCacheMisses;
private final double pageCacheHitRatio;
private final long time;

protected InternalProfiledPlan( String operatorType, Map<String, Value> arguments,
List<String> identifiers, List<ProfiledPlan> children, long dbHits, long records )
protected InternalProfiledPlan( String operatorType, Map<String,Value> arguments, List<String> identifiers, List<ProfiledPlan> children, long dbHits,
long records, long pageCacheHits, long pageCacheMisses, double pageCacheHitRatio, long time )
{
super( operatorType, arguments, identifiers, children );
this.dbHits = dbHits;
this.records = records;
this.pageCacheHits = pageCacheHits;
this.pageCacheMisses = pageCacheMisses;
this.pageCacheHitRatio = pageCacheHitRatio;
this.time = time;
}

@Override
Expand All @@ -50,17 +58,51 @@ public long records()
return records;
}

@Override
public boolean hasPageCacheStats()
{
return pageCacheHits > 0 || pageCacheMisses > 0 || !Double.isNaN( pageCacheHitRatio );
}

@Override
public long pageCacheHits()
{
return pageCacheHits;
}

@Override
public long pageCacheMisses()
{
return pageCacheMisses;
}

@Override
public double pageCacheHitRatio()
{
return pageCacheHitRatio;
}

@Override
public long time()
{
return time;
}

public static final PlanCreator<ProfiledPlan> PROFILED_PLAN = new PlanCreator<ProfiledPlan>()
{
@Override
public ProfiledPlan create( String operatorType, Map<String,Value> arguments, List<String> identifiers, List<ProfiledPlan> children, Value originalPlanValue )
public ProfiledPlan create( String operatorType, Map<String,Value> arguments, List<String> identifiers, List<ProfiledPlan> children,
Value originalPlanValue )
{
return new InternalProfiledPlan( operatorType, arguments, identifiers, children,
originalPlanValue.get( "dbHits" ).asLong(),
originalPlanValue.get( "rows" ).asLong() );
return new InternalProfiledPlan( operatorType, arguments, identifiers, children, originalPlanValue.get( "dbHits" ).asLong( 0 ),
originalPlanValue.get( "rows" ).asLong( 0 ), originalPlanValue.get( "pageCacheHits" ).asLong( 0 ),
originalPlanValue.get( "pageCacheMisses" ).asLong( 0 ), originalPlanValue.get( "pageCacheHitRatio" ).asDouble( Double.NaN ),
originalPlanValue.get( "time" ).asLong( 0 ) );
}
};

/** Builds a regular plan without profiling information - eg. a plan that came as a result of an `EXPLAIN` statement */
public static final Function<Value, ProfiledPlan> PROFILED_PLAN_FROM_VALUE = new Converter<>(PROFILED_PLAN);
/**
* Builds a regular plan without profiling information - eg. a plan that came as a result of an `EXPLAIN` statement
*/
public static final Function<Value,ProfiledPlan> PROFILED_PLAN_FROM_VALUE = new Converter<>( PROFILED_PLAN );
}
25 changes: 25 additions & 0 deletions driver/src/main/java/org/neo4j/driver/summary/ProfiledPlan.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,31 @@ public interface ProfiledPlan extends Plan
*/
long records();

/**
* @return if the number page cache hits and misses and the ratio was recorded.
*/
boolean hasPageCacheStats();

/**
* @return number of page cache hits caused by executing the associated execution step
*/
long pageCacheHits();

/**
* @return number of page cache misses caused by executing the associated execution step
*/
long pageCacheMisses();

/**
* @return the ratio of page cache hits to total number of lookups or {@link Double#NaN} if no data is available
*/
double pageCacheHitRatio();

/**
* @return amount of time spent in the associated execution step.
*/
long time();

@Override
List<ProfiledPlan> children();
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ void shouldContainProfile()

ProfiledPlan profile = summary.profile();

assertEquals( 0, profile.time() );
assertEquals( 0, profile.dbHits() );
assertEquals( 1, profile.records() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.HashMap;
import java.util.Map;

import org.neo4j.driver.internal.value.FloatValue;
import org.neo4j.driver.internal.value.IntegerValue;
import org.neo4j.driver.internal.value.ListValue;
import org.neo4j.driver.internal.value.MapValue;
Expand All @@ -35,6 +36,7 @@
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.junit.jupiter.api.Assertions.assertTrue;

class InternalProfiledPlanTest
{
Expand All @@ -49,12 +51,7 @@ void shouldHandlePlanWithNoChildren()
ProfiledPlan plan = InternalProfiledPlan.PROFILED_PLAN_FROM_VALUE.apply( value );

// THEN
assertThat( plan.dbHits(), equalTo( 42L ) );
assertThat( plan.records(), equalTo( 1337L ) );
assertThat( plan.operatorType(), equalTo( "AwesomeOperator" ) );
assertThat( plan.identifiers(), equalTo( asList( "n1", "n2" ) ) );
assertThat( plan.arguments().values(), hasItem( new StringValue( "CYPHER 1337" ) ) );
assertThat( plan.children(), empty() );
verifyPlan( plan );
}

@Test
Expand All @@ -71,12 +68,7 @@ void shouldHandlePlanWithChildren()
// THEN
for ( ProfiledPlan child : plan.children() )
{
assertThat( child.dbHits(), equalTo( 42L ) );
assertThat( child.records(), equalTo( 1337L ) );
assertThat( child.operatorType(), equalTo( "AwesomeOperator" ) );
assertThat( child.identifiers(), equalTo( asList( "n1", "n2" ) ) );
assertThat( child.arguments().values(), hasItem( new StringValue( "CYPHER 1337" ) ) );
assertThat( child.children(), empty() );
verifyPlan( child );
}
}

Expand All @@ -86,12 +78,29 @@ private Map<String,Value> createPlanMap()
map.put( "operatorType", new StringValue( "AwesomeOperator" ) );
map.put( "rows", new IntegerValue( 1337L ) );
map.put( "dbHits", new IntegerValue( 42 ) );
map.put( "pageCacheHits", new IntegerValue( 1234 ) );
map.put( "pageCacheMisses", new IntegerValue( 3456 ) );
map.put( "pageCacheHitRatio", new FloatValue( 0.123 ) );
map.put( "time", new IntegerValue( 999 ) );
map.put( "identifiers", new ListValue( new StringValue( "n1" ), new StringValue( "n2" ) ) );
Map<String,Value> args = new HashMap<>();
args.put( "version", new StringValue( "CYPHER 1337" ) );
map.put( "args", new MapValue( args ) );
return map;
}


private void verifyPlan( ProfiledPlan plan )
{
assertThat( plan.dbHits(), equalTo( 42L ) );
assertThat( plan.records(), equalTo( 1337L ) );
assertTrue( plan.hasPageCacheStats() );
assertThat( plan.pageCacheHits(), equalTo( 1234L ) );
assertThat( plan.pageCacheMisses(), equalTo( 3456L ) );
assertThat( plan.pageCacheHitRatio(), equalTo( 0.123 ) );
assertThat( plan.time(), equalTo( 999L ) );
assertThat( plan.operatorType(), equalTo( "AwesomeOperator" ) );
assertThat( plan.identifiers(), equalTo( asList( "n1", "n2" ) ) );
assertThat( plan.arguments().values(), hasItem( new StringValue( "CYPHER 1337" ) ) );
assertThat( plan.children(), empty() );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ void shouldBuildResultSummaryWithProfiledPlan()
"identifiers", values( "a", "b" ),
"rows", value( 424242 ),
"dbHits", value( 242424 ),
"time", value( 999 ),
"children", values(
parameters(
"operatorType", "LabelScan",
Expand All @@ -249,6 +250,11 @@ void shouldBuildResultSummaryWithProfiledPlan()
assertEquals( asList( "a", "b" ), summary.profile().identifiers() );
assertEquals( 424242, summary.profile().records() );
assertEquals( 242424, summary.profile().dbHits() );
assertEquals( 999, summary.profile().time() );
assertFalse( summary.profile().hasPageCacheStats() );
assertEquals( Double.NaN, summary.profile().pageCacheHitRatio() );
assertEquals( 0, summary.profile().pageCacheMisses() );
assertEquals( 0, summary.profile().pageCacheHits() );

List<ProfiledPlan> children = summary.profile().children();
assertEquals( 1, children.size() );
Expand Down