Skip to content

Commit 437dea4

Browse files
authored
Merge pull request #451 from lutovich/1.5-gc-improvements
Couple tweaks to generate less garbage
2 parents 91f5f06 + 964a934 commit 437dea4

24 files changed

+376
-342
lines changed

driver/src/main/java/org/neo4j/driver/internal/BoltServerAddress.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.net.UnknownHostException;
2626

2727
import static java.lang.String.format;
28+
import static java.util.Objects.requireNonNull;
2829

2930
/**
3031
* Holds a host and port pair that denotes a Bolt server address.
@@ -49,23 +50,23 @@ public BoltServerAddress( URI uri )
4950

5051
public BoltServerAddress( String host, int port )
5152
{
52-
this.host = host;
53+
this.host = requireNonNull( host );
5354
this.port = port;
5455
}
5556

5657
@Override
57-
public boolean equals( Object obj )
58+
public boolean equals( Object o )
5859
{
59-
if ( this == obj )
60+
if ( this == o )
6061
{
6162
return true;
6263
}
63-
if ( !(obj instanceof BoltServerAddress) )
64+
if ( o == null || getClass() != o.getClass() )
6465
{
6566
return false;
6667
}
67-
BoltServerAddress address = (BoltServerAddress) obj;
68-
return host.equals( address.host ) && port == address.port;
68+
BoltServerAddress that = (BoltServerAddress) o;
69+
return port == that.port && host.equals( that.host );
6970
}
7071

7172
@Override

driver/src/main/java/org/neo4j/driver/internal/Bookmark.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
package org.neo4j.driver.internal;
2020

2121
import java.util.Collections;
22-
import java.util.HashMap;
2322
import java.util.Iterator;
2423
import java.util.Map;
2524
import java.util.Objects;
@@ -28,6 +27,7 @@
2827

2928
import static java.util.Collections.emptyMap;
3029
import static java.util.Collections.singleton;
30+
import static org.neo4j.driver.internal.util.Iterables.newHashMapWithSize;
3131
import static org.neo4j.driver.v1.Values.value;
3232

3333
public final class Bookmark
@@ -93,7 +93,7 @@ public Map<String,Value> asBeginTransactionParameters()
9393
// {bookmarks: ["one", "two", "max"]} for backwards compatibility reasons. Old servers can only accept single
9494
// bookmark that is why driver has to parse and compare given list of bookmarks. This functionality will
9595
// eventually be removed.
96-
Map<String,Value> parameters = new HashMap<>( 4 );
96+
Map<String,Value> parameters = newHashMapWithSize( 2 );
9797
parameters.put( BOOKMARK_KEY, value( maxValue ) );
9898
parameters.put( BOOKMARKS_KEY, value( values ) );
9999
return parameters;

driver/src/main/java/org/neo4j/driver/internal/ExplicitTransaction.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
import static java.util.Collections.emptyMap;
4949
import static java.util.concurrent.CompletableFuture.completedFuture;
50+
import static org.neo4j.driver.internal.util.Futures.completedWithNull;
5051
import static org.neo4j.driver.internal.util.Futures.failedFuture;
5152
import static org.neo4j.driver.v1.Values.value;
5253

@@ -163,7 +164,7 @@ else if ( state == State.ACTIVE || state == State.MARKED_FAILED || state == Stat
163164
}
164165
else
165166
{
166-
return completedFuture( null );
167+
return completedWithNull();
167168
}
168169
}
169170

@@ -172,7 +173,7 @@ public CompletionStage<Void> commitAsync()
172173
{
173174
if ( state == State.COMMITTED )
174175
{
175-
return completedFuture( null );
176+
return completedWithNull();
176177
}
177178
else if ( state == State.ROLLED_BACK )
178179
{
@@ -200,13 +201,13 @@ public CompletionStage<Void> rollbackAsync()
200201
}
201202
else if ( state == State.ROLLED_BACK )
202203
{
203-
return completedFuture( null );
204+
return completedWithNull();
204205
}
205206
else if ( state == State.TERMINATED )
206207
{
207208
// transaction has been terminated by RESET and should be rolled back by the database
208209
state = State.ROLLED_BACK;
209-
return completedFuture( null );
210+
return completedWithNull();
210211
}
211212
else
212213
{

driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import org.neo4j.driver.v1.Logging;
3030
import org.neo4j.driver.v1.Session;
3131

32-
import static java.util.concurrent.CompletableFuture.completedFuture;
32+
import static org.neo4j.driver.internal.util.Futures.completedWithNull;
3333

3434
public class InternalDriver implements Driver
3535
{
@@ -116,7 +116,7 @@ public CompletionStage<Void> closeAsync()
116116
log.info( "Closing driver instance %s", this );
117117
return sessionFactory.close();
118118
}
119-
return completedFuture( null );
119+
return completedWithNull();
120120
}
121121

122122
public CompletionStage<Void> verifyConnectivity()

driver/src/main/java/org/neo4j/driver/internal/InternalStatementResultCursor.java

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
*/
1919
package org.neo4j.driver.internal;
2020

21-
import java.util.ArrayList;
2221
import java.util.List;
2322
import java.util.concurrent.CompletableFuture;
2423
import java.util.concurrent.CompletionStage;
@@ -118,9 +117,7 @@ public CompletionStage<List<Record>> listAsync()
118117
@Override
119118
public <T> CompletionStage<List<T>> listAsync( Function<Record,T> mapFunction )
120119
{
121-
CompletableFuture<List<T>> resultFuture = new CompletableFuture<>();
122-
internalListAsync( new ArrayList<>(), resultFuture, mapFunction );
123-
return resultFuture;
120+
return pullAllHandler.listAsync( mapFunction );
124121
}
125122

126123
public CompletionStage<Throwable> failureAsync()
@@ -160,40 +157,4 @@ else if ( record != null )
160157
}
161158
} );
162159
}
163-
164-
private <T> void internalListAsync( List<T> result, CompletableFuture<List<T>> resultFuture,
165-
Function<Record,T> mapFunction )
166-
{
167-
CompletionStage<Record> recordFuture = nextAsync();
168-
169-
// use async completion listener because of recursion, otherwise it is possible for
170-
// the caller thread to get StackOverflowError when result is large and buffered
171-
recordFuture.whenCompleteAsync( ( record, completionError ) ->
172-
{
173-
Throwable error = Futures.completionExceptionCause( completionError );
174-
if ( error != null )
175-
{
176-
resultFuture.completeExceptionally( error );
177-
}
178-
else if ( record != null )
179-
{
180-
T value;
181-
try
182-
{
183-
value = mapFunction.apply( record );
184-
}
185-
catch ( Throwable mapError )
186-
{
187-
resultFuture.completeExceptionally( mapError );
188-
return;
189-
}
190-
result.add( value );
191-
internalListAsync( result, resultFuture, mapFunction );
192-
}
193-
else
194-
{
195-
resultFuture.complete( result );
196-
}
197-
} );
198-
}
199160
}

driver/src/main/java/org/neo4j/driver/internal/NetworkSession.java

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
import org.neo4j.driver.v1.exceptions.ClientException;
4747
import org.neo4j.driver.v1.types.TypeSystem;
4848

49-
import static java.util.concurrent.CompletableFuture.completedFuture;
49+
import static org.neo4j.driver.internal.util.Futures.completedWithNull;
5050
import static org.neo4j.driver.internal.util.Futures.failedFuture;
5151
import static org.neo4j.driver.v1.Values.value;
5252

@@ -60,9 +60,9 @@ public class NetworkSession implements Session
6060
protected final Logger logger;
6161

6262
private volatile Bookmark bookmark = Bookmark.empty();
63-
private volatile CompletionStage<ExplicitTransaction> transactionStage = completedFuture( null );
64-
private volatile CompletionStage<Connection> connectionStage = completedFuture( null );
65-
private volatile CompletionStage<InternalStatementResultCursor> resultCursorStage = completedFuture( null );
63+
private volatile CompletionStage<ExplicitTransaction> transactionStage = completedWithNull();
64+
private volatile CompletionStage<Connection> connectionStage = completedWithNull();
65+
private volatile CompletionStage<InternalStatementResultCursor> resultCursorStage = completedWithNull();
6666

6767
private final AtomicBoolean open = new AtomicBoolean( true );
6868

@@ -168,7 +168,7 @@ public CompletionStage<Void> closeAsync()
168168
{
169169
if ( cursor == null )
170170
{
171-
return completedFuture( null );
171+
return completedWithNull();
172172
}
173173
return cursor.failureAsync();
174174
} ).thenCompose( error -> releaseResources().thenApply( ignore ->
@@ -186,7 +186,7 @@ public CompletionStage<Void> closeAsync()
186186
}
187187
} ) );
188188
}
189-
return completedFuture( null );
189+
return completedWithNull();
190190
}
191191

192192
@Override
@@ -274,10 +274,6 @@ public TypeSystem typeSystem()
274274

275275
CompletionStage<Boolean> currentConnectionIsOpen()
276276
{
277-
if ( connectionStage == null )
278-
{
279-
return completedFuture( false );
280-
}
281277
return connectionStage.handle( ( connection, error ) ->
282278
error == null && // no acquisition error
283279
connection != null && // some connection has actually been acquired
@@ -363,7 +359,7 @@ private <T> CompletionStage<T> safeExecuteWork( ExplicitTransaction tx, Transact
363359
CompletionStage<T> result = work.execute( tx );
364360

365361
// protect from given transaction function returning null
366-
return result == null ? completedFuture( null ) : result;
362+
return result == null ? completedWithNull() : result;
367363
}
368364
catch ( Throwable workError )
369365
{
@@ -459,7 +455,7 @@ private CompletionStage<Connection> acquireConnection( AccessMode mode )
459455
{
460456
if ( cursor == null )
461457
{
462-
return completedFuture( null );
458+
return completedWithNull();
463459
}
464460
// make sure previous result is fully consumed and connection is released back to the pool
465461
return cursor.failureAsync();
@@ -508,7 +504,7 @@ private CompletionStage<Void> rollbackTransaction()
508504
{
509505
return tx.rollbackAsync();
510506
}
511-
return completedFuture( null );
507+
return completedWithNull();
512508
} ).exceptionally( error ->
513509
{
514510
Throwable cause = Futures.completionExceptionCause( error );
@@ -519,13 +515,13 @@ private CompletionStage<Void> rollbackTransaction()
519515

520516
private CompletionStage<Void> releaseConnection()
521517
{
522-
return existingConnectionOrNull().thenCompose( connection ->
518+
return connectionStage.thenCompose( connection ->
523519
{
524520
if ( connection != null )
525521
{
526522
return connection.release();
527523
}
528-
return completedFuture( null );
524+
return completedWithNull();
529525
} );
530526
}
531527

@@ -574,15 +570,10 @@ private CompletionStage<Void> ensureNoOpenTx( String errorMessage )
574570
private CompletionStage<ExplicitTransaction> existingTransactionOrNull()
575571
{
576572
return transactionStage
577-
.exceptionally( error -> null ) // handle previous acquisition failures
573+
.exceptionally( error -> null ) // handle previous connection acquisition and tx begin failures
578574
.thenApply( tx -> tx != null && tx.isOpen() ? tx : null );
579575
}
580576

581-
private CompletionStage<Connection> existingConnectionOrNull()
582-
{
583-
return connectionStage.exceptionally( error -> null ); // handle previous acquisition failures
584-
}
585-
586577
private void ensureSessionIsOpen()
587578
{
588579
if ( !open.get() )

driver/src/main/java/org/neo4j/driver/internal/async/ResultCursorsHolder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.neo4j.driver.internal.InternalStatementResultCursor;
2727

2828
import static java.util.concurrent.CompletableFuture.completedFuture;
29+
import static org.neo4j.driver.internal.util.Futures.completedWithNull;
2930

3031
public class ResultCursorsHolder
3132
{
@@ -41,14 +42,14 @@ public CompletionStage<Throwable> retrieveNotConsumedError()
4142
{
4243
return cursorStages.stream()
4344
.map( this::retrieveFailure )
44-
.reduce( completedFuture( null ), this::nonNullFailureFromEither );
45+
.reduce( completedWithNull(), this::nonNullFailureFromEither );
4546
}
4647

4748
private CompletionStage<Throwable> retrieveFailure( CompletionStage<InternalStatementResultCursor> cursorStage )
4849
{
4950
return cursorStage
5051
.exceptionally( cursor -> null )
51-
.thenCompose( cursor -> cursor == null ? completedFuture( null ) : cursor.failureAsync() );
52+
.thenCompose( cursor -> cursor == null ? completedWithNull() : cursor.failureAsync() );
5253
}
5354

5455
private CompletionStage<Throwable> nonNullFailureFromEither( CompletionStage<Throwable> stage1,

0 commit comments

Comments
 (0)