auphong2707/dl4se-code-review-dataset huggingface dataset:
Source:
public Class<? extends ArrayAggregationState> getGroupedStateClass() { if (mode == NEW) { return GroupArrayAggregationState.class; } if (mode == LEGACY) { return LegacyArrayAggregationGroupState.class; } START throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, format("Unexpected group enum type %s", mode)); END } Use `switch` instead of `if`s

Target:
public Class<? extends ArrayAggregationState> getGroupedStateClass() { switch (mode) { case NEW: return GroupArrayAggregationState.class; case LEGACY: return LegacyArrayAggregationGroupState.class; default: throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, format("Unexpected group enum type %s", mode)); } }
Source:
public DecimalStatistics(BigDecimal minimum, BigDecimal maximum, long decimalSizeInBytes) START { END checkArgument(minimum == null || maximum == null || minimum.compareTo(maximum) <= 0, "minimum is not less than maximum"); this.minimum = minimum; this.maximum = maximum; int retainedSizeInBytes = 0; if (minimum != null) { retainedSizeInBytes += BIG_DECIMAL_INSTANCE_SIZE + decimalSizeInBytes; } if (maximum != null) { retainedSizeInBytes += BIG_DECIMAL_INSTANCE_SIZE + decimalSizeInBytes; } this.retainedSizeInBytes = retainedSizeInBytes + INSTANCE_SIZE; } at some point we should switch this to our decimal library which can represent these as two longs

Target:
public DecimalStatistics(BigDecimal minimum, BigDecimal maximum, long decimalSizeInBytes) { checkArgument(minimum == null || maximum == null || minimum.compareTo(maximum) <= 0, "minimum is not less than maximum"); this.minimum = minimum; this.maximum = maximum; int retainedSizeInBytes = 0; if (minimum != null) { retainedSizeInBytes += BIG_DECIMAL_INSTANCE_SIZE + decimalSizeInBytes; } if (maximum != null && minimum != maximum) { retainedSizeInBytes += BIG_DECIMAL_INSTANCE_SIZE + decimalSizeInBytes; } this.retainedSizeInBytes = retainedSizeInBytes + INSTANCE_SIZE; }
Source:
START public static double stXMax(@SqlType(GEOMETRY_TYPE_NAME) Slice input) END { Envelope envelope = deserializeEnvelope(input); if (envelope == null) { return 0.0; } return envelope.getXMax(); } - please squash the commits - fix commit message. `Optimize Min Max geospatial functions` is too generic, instead please describe what you changed which resulted with better performance of min max geospatial functions.

Target:
public static Double stXMax(@SqlType(GEOMETRY_TYPE_NAME) Slice input) { Envelope envelope = deserializeEnvelope(input); if (envelope == null) { return null; } return envelope.getXMax(); }
Source:
public double simpleGeometry(BenchmarkData data) { START return GeoFunctions.stXMin(data.simpleGeometry); END } static import `stXMin`.

Target:
public double simpleGeometry(BenchmarkData data) { return stXMin(data.simpleGeometry); }
Source:
public void setup() throws IOException { START complexGeometry = GeoFunctions.stGeometryFromText(Slices.utf8Slice(loadPolygon("large_polygon.txt"))); END simpleGeometry = GeoFunctions.stGeometryFromText(Slices.utf8Slice("POLYGON ((1 1, 4 1, 1 4))")); } static import `stGeometryFromText` and `utf8Slice`.

Target:
public void setup() throws IOException { complexGeometry = stGeometryFromText(utf8Slice(loadPolygon("large_polygon.txt"))); simpleGeometry = stGeometryFromText(utf8Slice("POLYGON ((1 1, 4 1, 1 4))")); }
Source:
public void acknowledgeTaskResults(TaskId taskId, OutputBufferId bufferId, long sequenceId) { requireNonNull(taskId, "taskId is null"); requireNonNull(bufferId, "bufferId is null"); START Preconditions.checkArgument(sequenceId >= 0, "sequenceId is negative"); END tasks.getUnchecked(taskId).acknowledgeTaskResults(bufferId, sequenceId); } static import

Target:
public void acknowledgeTaskResults(TaskId taskId, OutputBufferId bufferId, long sequenceId) { requireNonNull(taskId, "taskId is null"); requireNonNull(bufferId, "bufferId is null"); checkArgument(sequenceId >= 0, "sequenceId is negative"); tasks.getUnchecked(taskId).acknowledgeTaskResults(bufferId, sequenceId); }
Source:
START public List<Expression> rewrite(List<Expression> items, Context<C> context) END { ImmutableList.Builder<Expression> builder = ImmutableList.builder(); for (Expression expression : items) { builder.add(rewrite(expression, context.get())); } return builder.build(); } This should probably be `private`.

Target:
private List<Expression> rewrite(List<Expression> items, Context<C> context) { ImmutableList.Builder<Expression> builder = ImmutableList.builder(); for (Expression expression : items) { builder.add(rewrite(expression, context.get())); } return builder.build(); }
Source:
public void start() { DateTime now = DateTime.now(); executionStartTime.compareAndSet(null, now); startNanos.compareAndSet(0, System.nanoTime()); startFullGcCount.compareAndSet(0, gcMonitor.getMajorGcCount()); START startFullGcTimeNanos.compareAndSet(0, gcMonitor.getMajorGcTime().roundTo(NANOSECONDS)); END // always update last execution start time lastExecutionStartTime.set(now); } 0 is not a reasonable initial value for these two fields. Use -1 instead. I would imagine that these two values will stay at 0 for a long time after VM start.

Target:
public void start() { DateTime now = DateTime.now(); executionStartTime.compareAndSet(null, now); startNanos.compareAndSet(0, System.nanoTime()); startFullGcCount.compareAndSet(-1, gcMonitor.getMajorGcCount()); startFullGcTimeNanos.compareAndSet(-1, gcMonitor.getMajorGcTime().roundTo(NANOSECONDS)); // always update last execution start time lastExecutionStartTime.set(now); }
Source:
public void testValues() { assertQuery("VALUES 1, 2, 3, 4"); assertQuery("VALUES 1, 3, 2, 4 ORDER BY 1", "SELECT * FROM (VALUES 1, 3, 2, 4) ORDER BY 1"); assertQuery("VALUES (1.1, 2, 'foo'), (sin(3.3), 2+2, 'bar')"); assertQuery("VALUES (1.1, 2), (sin(3.3), 2+2) ORDER BY 1", "VALUES (sin(3.3), 2+2), (1.1, 2)"); assertQuery("VALUES (1.1, 2), (sin(3.3), 2+2) LIMIT 1", "VALUES (1.1, 2)"); assertQuery("SELECT * FROM (VALUES (1.1, 2), (sin(3.3), 2+2))"); assertQuery( "SELECT * FROM (VALUES (1.1, 2), (sin(3.3), 2+2)) x (a, b) LEFT JOIN (VALUES (1.1, 2), (1.1, 2+2)) y (a, b) USING (a)", START "VALUES (1.1, 2, 4), (1.1, 2, 2), (sin(3.3), 4, NULL)"); END assertQuery("SELECT 1.1 in (VALUES (1.1), (2.2))", "VALUES (TRUE)"); assertQuery("" + "WITH a AS (VALUES (1.1, 2), (sin(3.3), 2+2)) " + "SELECT * FROM a", "VALUES (1.1, 2), (sin(3.3), 2+2)"); // implicity coersions assertQuery("VALUES 1, 2.2, 3, 4.4"); assertQuery("VALUES (1, 2), (3.3, 4.4)"); assertQuery("VALUES true, 1.0 in (1, 2, 3)"); } If these queries are covered by `TestJoinUsing`, then maybe we could remove them from here?

Target:
public void testValues() { assertQuery("VALUES 1, 2, 3, 4"); assertQuery("VALUES 1, 3, 2, 4 ORDER BY 1", "SELECT * FROM (VALUES 1, 3, 2, 4) ORDER BY 1"); assertQuery("VALUES (1.1, 2, 'foo'), (sin(3.3), 2+2, 'bar')"); assertQuery("VALUES (1.1, 2), (sin(3.3), 2+2) ORDER BY 1", "VALUES (sin(3.3), 2+2), (1.1, 2)"); assertQuery("VALUES (1.1, 2), (sin(3.3), 2+2) LIMIT 1", "VALUES (1.1, 2)"); assertQuery("SELECT * FROM (VALUES (1.1, 2), (sin(3.3), 2+2))"); assertQuery("SELECT 1.1 in (VALUES (1.1), (2.2))", "VALUES (TRUE)"); assertQuery("" + "WITH a AS (VALUES (1.1, 2), (sin(3.3), 2+2)) " + "SELECT * FROM a", "VALUES (1.1, 2), (sin(3.3), 2+2)"); // implicity coersions assertQuery("VALUES 1, 2.2, 3, 4.4"); assertQuery("VALUES (1, 2), (3.3, 4.4)"); assertQuery("VALUES true, 1.0 in (1, 2, 3)"); }
Source:
public void cleanup() throws IOException { START getMetastoreClient(TEST_DB_NAME).dropDatabase(TEST_DB_NAME); END deleteRecursively(tempDir.toPath(), ALLOW_INSECURE); } Nice fix!

Target:
public void cleanup() throws IOException { try { getMetastoreClient(TEST_DB_NAME).dropDatabase(TEST_DB_NAME); } finally { deleteRecursively(tempDir.toPath(), ALLOW_INSECURE); } }
Source:
START private void assertColumnList(List<com.amazonaws.services.glue.model.Column> actual, List<Column> expected) END { if (expected == null) { assertNull(actual); } assertEquals(actual.size(), expected.size()); for (int i = 0; i < expected.size(); i++) { assertColumn(actual.get(i), expected.get(i)); } } I think all these `assert` methods can be static

Target:
private static void assertColumnList(List<com.amazonaws.services.glue.model.Column> actual, List<Column> expected) { if (expected == null) { assertNull(actual); } assertEquals(actual.size(), expected.size()); for (int i = 0; i < expected.size(); i++) { assertColumn(actual.get(i), expected.get(i)); } }
Source:
START private void assertColumnList(List<Column> actual, List<com.amazonaws.services.glue.model.Column> expected) END { if (expected == null) { assertNull(actual); } assertEquals(actual.size(), expected.size()); for (int i = 0; i < expected.size(); i++) { assertColumn(actual.get(i), expected.get(i)); } } Same here, see if these can be static

Target:
private static void assertColumnList(List<Column> actual, List<com.amazonaws.services.glue.model.Column> expected) { if (expected == null) { assertNull(actual); } assertEquals(actual.size(), expected.size()); for (int i = 0; i < expected.size(); i++) { assertColumn(actual.get(i), expected.get(i)); } }
Source:
public void testNoFrom() { START assertQuery("SELECT 1 + 2, 3 + 4", "SELECT 1 + 2, 3 + 4"); END } `expected` and `actual` SQLs are now same, use simpler `assertQuery` overload

Target:
public void testNoFrom() { assertQuery("SELECT 1 + 2, 3 + 4"); }
Source:
protected TestQueryPlanDeterminism() { START super(TestQueryPlanDeterminism::createLocalQueryRunner, FeatureSelection.all().without(ENGINE_ONLY).build()); END } really? not the other way around (e.g: include engine/planner only) features?

Target:
protected TestQueryPlanDeterminism() { super(TestQueryPlanDeterminism::createLocalQueryRunner); }
Source:
public TestDistributedQueriesNoHashGeneration() { START super(() -> createQueryRunner(ImmutableMap.of(), ImmutableMap.of("optimizer.optimize-hash-generation", "false")), FeatureSelection.all().without(ENGINE_ONLY).build()); END } maybe we could make shortcut for: `FeatureSelection.all().without(ENGINE_ONLY).build()`?

Target:
public TestDistributedQueriesNoHashGeneration() { super(() -> createQueryRunner(ImmutableMap.of(), ImmutableMap.of("optimizer.optimize-hash-generation", "false"))); }
Source:
protected AbstractTestIntegrationSmokeTest(QueryRunnerSupplier supplier) { START super(supplier, FeatureSelection.all()); END } nit: `AbstractTestIntegrationSmokeTest` doesn't make use of feature selection (if it did, a constructor accepting feature selection would be needed). Therefore the superclass (`AbstractTestQueryFramework`) should still provide a constructor that doesn't require passing feature selection.

Target:
protected AbstractTestIntegrationSmokeTest(QueryRunnerSupplier supplier) { super(supplier); }
Source:
public StreamProperties visitSort(SortNode node, List<StreamProperties> inputProperties) { StreamProperties sourceProperties = Iterables.getOnlyElement(inputProperties); START if (sourceProperties.isSingleStream()) { END // stream is only sorted if sort operator is executed without parallelism return StreamProperties.ordered(); } else { return sourceProperties; } } maybe it should be in a `checkState` as currently it would mean that there is a bug somewhere, no point of having parallel sort without a merge

Target:
public StreamProperties visitSort(SortNode node, List<StreamProperties> inputProperties) { StreamProperties sourceProperties = Iterables.getOnlyElement(inputProperties); if (sourceProperties.isSingleStream()) { // stream is only sorted if sort operator is executed without parallelism return StreamProperties.ordered(); } return sourceProperties; }
Source:
private List<SchemaTableName> listTables(ConnectorSession session, SchemaTablePrefix prefix) { if (prefix.getTableName() == null) { return listTables(session, prefix.getSchemaName()); } START return ImmutableList.of(new SchemaTableName(prefix.getSchemaName(), prefix.getTableName())); END } What if `schemaName` is `null` here?

Target:
private List<SchemaTableName> listTables(ConnectorSession session, SchemaTablePrefix prefix) { if (prefix.getSchemaName() == null || prefix.getTableName() == null) { return listTables(session, prefix.getSchemaName()); } return ImmutableList.of(new SchemaTableName(prefix.getSchemaName(), prefix.getTableName())); }
Source:
public boolean needsInput() { return !finishing && lookupSourceProviderFuture.isDone() && spillInProgress.isDone() && probe == null && outputPage == null START && !isLookupSourceEmpty(); END } Check this right after `lookupSourceProviderFuture.isDone()`... or better yet, don't check it here at all, check in `tryFetchLookupSourceProvider`

Target:
public boolean needsInput() { return !finishing && lookupSourceProviderFuture.isDone() && spillInProgress.isDone() && probe == null && outputPage == null; }
Source:
public boolean isFinished() { boolean finished = (this.finished && probe == null && pageBuilder.isEmpty() && outputPage == null) || START isLookupSourceEmpty(); END // if finished drop references so memory is freed early if (finished) { close(); } return finished; } Instead of inspecting repeatedly whether lookup source is empty, you could leverage the fact that this information doesn't change, ever. So, instead of this change (and instead of introducing the `isLookupSourceEmpty` method), you can inspect `lookupSource` only once, in `tryFetchLookupSourceProvider`, and set `finishing` flag when the LS is empty.

Target:
public boolean isFinished() { boolean finished = this.finished && probe == null && pageBuilder.isEmpty() && outputPage == null; // if finished drop references so memory is freed early if (finished) { close(); } return finished; }
Source:
public void testStatsCalculatorUsesLayout() { assertPlan("SELECT orderstatus FROM orders WHERE orderstatus = 'P'", anyTree( node(TableScanNode.class) .withStats(PlanNodeStatsEstimate.builder() .setOutputRowCount(new Estimate(363.0)) .setOutputSizeInBytes(unknownValue()) .build()))); assertPlan("SELECT orderstatus FROM orders WHERE orderkey = 42", anyTree( node(TableScanNode.class) .withStats(PlanNodeStatsEstimate.builder() .setOutputRowCount(new Estimate(15000.0)) .setOutputSizeInBytes(unknownValue()) .build()))); START } END it looks unrelated

Target:
public void testStatsCalculatorUsesLayout() { assertPlan("SELECT orderstatus FROM orders WHERE orderstatus = 'P'", anyTree( node(TableScanNode.class) .withStats(PlanNodeStatsEstimate.builder() .setOutputRowCount(363.0) .build()))); assertPlan("SELECT orderstatus FROM orders WHERE orderkey = 42", anyTree( node(TableScanNode.class) .withStats(PlanNodeStatsEstimate.builder() .setOutputRowCount(15000.0) .build()))); }
Source:
public synchronized void stateChanged(TaskStatus newStatus) { long currentUserMemory = newStatus.getMemoryReservation().toBytes(); long currentSystemMemory = newStatus.getSystemMemoryReservation().toBytes(); long deltaUserMemoryInBytes = currentUserMemory - previousUserMemory; long deltaSystemMemoryInBytes = currentSystemMemory - previousSystemMemory; previousUserMemory = currentUserMemory; previousSystemMemory = currentSystemMemory; START stateMachine.updateMemoryUsage(deltaUserMemoryInBytes, deltaSystemMemoryInBytes); END } The existing code was unnecessarily roundabout. It can be simplified. Here, we have the absolute number, and we turn it into delta. In `QueryStateMachine.updateMemoryUsage`, it takes the delta, and converts it back to absolute value.

Target:
public synchronized void stateChanged(TaskStatus newStatus) { long currentUserMemory = newStatus.getMemoryReservation().toBytes(); long currentSystemMemory = newStatus.getSystemMemoryReservation().toBytes(); stateMachine.updateMemoryUsage(currentUserMemory, currentSystemMemory); }
Source:
public List<String> setUGI(String userName, List<String> groupNames) { START groupNames.add(userName); END return groupNames; } why do you modify input `paratemeter`. Maybe instead of this please return a copied list.

Target:
public List<String> setUGI(String userName, List<String> groupNames) { List<String> result = new ArrayList(groupNames); result.add(userName); return result; }
Source:
protected BaseRuleTest() { START this(TpchConnectorFactory.DEFAULT_PREDICATE_PUSHDOWN_ENABLED); END } from testing point of view, using explicit `false` (or whatever this is) would be better. i.e., if tpch connector decides to change its default, should presto tests change their behavior and coverage?

Target:
protected BaseRuleTest() { this(false); }
Source:
START private void checkNotHoldsLock(Object lock) END { checkState(!Thread.holdsLock(lock), "Cannot execute this method while holding a lock"); } make it `static`

Target:
private static void checkNotHoldsLock(Object lock) { checkState(!Thread.holdsLock(lock), "Cannot execute this method while holding a lock"); }
Source:
public long getEstimatedSizeInBytes() { START long hashMemorySizeInBytes = groupByHash == null ? 0 : groupByHash.getEstimatedSize(); END return INSTANCE_SIZE + memorySizeInBytes + hashMemorySizeInBytes + groupedRows.sizeOf() + pageReferences.sizeOf() + emptyPageReferenceSlots.getEstimatedSizeInBytes(); } groupByHash is never null

Target:
public long getEstimatedSizeInBytes() { return INSTANCE_SIZE + memorySizeInBytes + groupByHash.getEstimatedSize() + groupedRows.sizeOf() + pageReferences.sizeOf() + emptyPageReferenceSlots.getEstimatedSizeInBytes(); }
Source:
public void addInput(Page page) { requireNonNull(page, "page is null"); checkState(!isFinished(), "Operator is already finished"); Block sourceBlock = page.getBlock(setChannel); Page sourcePage = hashChannel.isPresent() ? new Page(sourceBlock, page.getBlock(hashChannel.get())) : new Page(sourceBlock); unfinishedWork = channelSetBuilder.addPage(sourcePage); processUnfinishedWork(); START channelSetBuilder.updateMemoryReservation(); END } How many times per page `OperatorContext#setMemoryReservation` is being called now?

Target:
public void addInput(Page page) { requireNonNull(page, "page is null"); checkState(!isFinished(), "Operator is already finished"); Block sourceBlock = page.getBlock(setChannel); Page sourcePage = hashChannel.isPresent() ? new Page(sourceBlock, page.getBlock(hashChannel.get())) : new Page(sourceBlock); unfinishedWork = channelSetBuilder.addPage(sourcePage); processUnfinishedWork(); }
Source:
public Work<?> addPage(Page page) { // Just add the page to the pending work, which will be processed later. START Work<?> work = hash.addPage(page); END return work; } inline: ```java return hash.addPage(page);

Target:
public Work<?> addPage(Page page) { // Just add the page to the pending work, which will be processed later. return hash.addPage(page); }
Source:
public boolean needsInput() { // Since SetBuilderOperator doesn't produce any output, the getOutput() // method may never be called. We need to handle any unfinished work // before addInput() can be called again. START if (unfinishedWork.isPresent() && !processUnfinishedWork()) { END return false; } return !finished; } inline: ```java return !finished && (!unfinishedWork.isPresent() || processUnfinishedWork());

Target:
public boolean needsInput() { // Since SetBuilderOperator doesn't produce any output, the getOutput() // method may never be called. We need to handle any unfinished work // before addInput() can be called again. return !finished && (unfinishedWork == null || processUnfinishedWork()); }
Source:
public int partitions() { lock.readLock().lock(); try { START return partitions.length; END } finally { lock.readLock().unlock(); } } `partitions.length` is final, because `partitions` is final, so this doesn't need the lock. Are you adding this to get a code analysis tool happy?

Target:
public int partitions() { return partitions.length; }
Source:
START protected static ReadMapping dateReadMapping() END { return longReadMapping(DATE, (resultSet, columnIndex) -> { // JDBC returns a date using a timestamp at midnight in the JVM timezone long localMillis = resultSet.getDate(columnIndex).getTime(); // Convert it to a midnight in UTC long utcMillis = ISOChronology.getInstance().getZone().getMillisKeepLocal(UTC, localMillis); // convert to days return MILLISECONDS.toDays(utcMillis); }); } These should also be public, as connectors which extend the base one won't be in the same package.

Target:
public static ReadMapping dateReadMapping() { return longReadMapping(DATE, (resultSet, columnIndex) -> { // JDBC returns a date using a timestamp at midnight in the JVM timezone long localMillis = resultSet.getDate(columnIndex).getTime(); // Convert it to a midnight in UTC long utcMillis = ISOChronology.getInstance().getZone().getMillisKeepLocal(UTC, localMillis); // convert to days return MILLISECONDS.toDays(utcMillis); }); }
Source:
public static long fromUnixTime(@SqlType(StandardTypes.DOUBLE) double unixTime, @SqlType(StandardTypes.BIGINT) long hoursOffset, @SqlType(StandardTypes.BIGINT) long minutesOffset) { int offset = toIntExact(hoursOffset * 60 + minutesOffset); TimeZoneKey timeZoneKey; try { timeZoneKey = getTimeZoneKeyForOffset(offset); } catch (IllegalArgumentException e) { START throw new PrestoException(INVALID_FUNCTION_ARGUMENT, format("Invalid offset: %d", offset), e); END } return packDateTimeWithZone(Math.round(unixTime * 1000), timeZoneKey); } You can do without `format` here: `"Invalid offset: " + offset`

Target:
public static long fromUnixTime(@SqlType(StandardTypes.DOUBLE) double unixTime, @SqlType(StandardTypes.BIGINT) long hoursOffset, @SqlType(StandardTypes.BIGINT) long minutesOffset) { TimeZoneKey timeZoneKey; try { timeZoneKey = getTimeZoneKeyForOffset((int) (hoursOffset * 60 + minutesOffset)); } catch (IllegalArgumentException e) { throw new PrestoException(INVALID_FUNCTION_ARGUMENT, e); } return packDateTimeWithZone(Math.round(unixTime * 1000), timeZoneKey); }
Source:
private Iterator<Page> readPages() { checkState(writable, "Repeated reads are disallowed to prevent potential resource leaks"); writable = false; try { InputStream input = targetFile.newInputStream(); START Closeable resources = closer.register(input); END Iterator<Page> pages = PagesSerdeUtil.readPages(serde, new InputStreamSliceInput(input, BUFFER_SIZE)); return PrestoIterators.closeWhenExhausted(pages, resources); } catch (IOException e) { throw new PrestoException(GENERIC_INTERNAL_ERROR, "Failed to read spilled pages", e); } } `resources` is now just `input`. Remove the variable: ``` InputStream input = closer.register(targetFile.newInputStream()); ```

Target:
private Iterator<Page> readPages() { checkState(writable, "Repeated reads are disallowed to prevent potential resource leaks"); writable = false; try { InputStream input = closer.register(targetFile.newInputStream()); Iterator<Page> pages = PagesSerdeUtil.readPages(serde, new InputStreamSliceInput(input, BUFFER_SIZE)); return PrestoIterators.closeWhenExhausted(pages, input); } catch (IOException e) { throw new PrestoException(GENERIC_INTERNAL_ERROR, "Failed to read spilled pages", e); } }
Source:
public void close() { try (Closer closer = Closer.create()) { closer.register(userAggregateMemoryContext::close); closer.register(revocableAggregateMemoryContext::close); closer.register(systemAggregateMemoryContext::close); START userLocalMemoryContext.close(); END revocableLocalMemoryContext.close(); systemLocalMemoryContext.close(); } catch (IOException e) { throw new RuntimeException("Exception closing memory tracking context", e); } } Why not `closer.register(...::close)`, as above?

Target:
public void close() { try (Closer closer = Closer.create()) { closer.register(userAggregateMemoryContext::close); closer.register(revocableAggregateMemoryContext::close); closer.register(systemAggregateMemoryContext::close); closer.register(userLocalMemoryContext::close); closer.register(revocableLocalMemoryContext::close); closer.register(systemLocalMemoryContext::close); } catch (IOException e) { throw new RuntimeException("Exception closing memory tracking context", e); } }
Source:
START public synchronized ListenableFuture<?> updateUserMemory(long delta) END { if (delta >= 0) { if (queryMemoryContext.getUserMemory() + delta > maxMemory) { throw exceededLocalLimit(succinctBytes(maxMemory)); } return memoryPool.reserve(queryId, delta); } memoryPool.free(queryId, -delta); return NOT_BLOCKED; } `private`

Target:
private synchronized ListenableFuture<?> updateUserMemory(long delta) { if (delta >= 0) { if (queryMemoryContext.getUserMemory() + delta > maxMemory) { throw exceededLocalLimit(succinctBytes(maxMemory)); } return memoryPool.reserve(queryId, delta); } memoryPool.free(queryId, -delta); return NOT_BLOCKED; }
Source:
public TaskContext addTaskContext(TaskStateMachine taskStateMachine, Session session, boolean verboseStats, boolean cpuTimerEnabled) { MemoryTrackingContext taskMemoryContext; synchronized (this) { START taskMemoryContext = queryMemoryContext.newMemoryTrackingContext(); END } TaskContext taskContext = TaskContext.createTaskContext( this, taskStateMachine, notificationExecutor, yieldExecutor, session, taskMemoryContext, verboseStats, cpuTimerEnabled); taskContexts.put(taskStateMachine.getTaskId(), taskContext); return taskContext; } `queryMemoryContext` is `final` and `@ThreadSafe`. What is this synchronization for?

Target:
public TaskContext addTaskContext(TaskStateMachine taskStateMachine, Session session, boolean verboseStats, boolean cpuTimerEnabled) { TaskContext taskContext = TaskContext.createTaskContext( this, taskStateMachine, notificationExecutor, yieldExecutor, session, queryMemoryContext.newMemoryTrackingContext(), verboseStats, cpuTimerEnabled); taskContexts.put(taskStateMachine.getTaskId(), taskContext); return taskContext; }
Source:
public boolean trySetBytes(long bytes) { boolean result = delegate.trySetBytes(bytes); if (peakMemory.isPresent()) { START peakMemory.get().accumulateAndGet(delegate.getBytes(), Math::max); END } return result; } You can spare this call when `!result`

Target:
public boolean trySetBytes(long bytes) { return delegate.trySetBytes(bytes); }
Source:
START public synchronized long getReservedRevocableBytes() END { return operatorMemoryContext.getRevocableMemory(); } remove `synchronized`

Target:
public long getReservedRevocableBytes() { return operatorMemoryContext.getRevocableMemory(); }
Source:
static long addExact(long usedBytes, long bytes) { try { return Math.addExact(usedBytes, bytes); } catch (ArithmeticException e) { START throw new RuntimeException(String.format("Overflow detected. usedBytes: %d, bytes: %d", usedBytes, bytes), e); END } } static import `format`

Target:
static long addExact(long usedBytes, long bytes) { try { return Math.addExact(usedBytes, bytes); } catch (ArithmeticException e) { throw new RuntimeException(format("Overflow detected. usedBytes: %d, bytes: %d", usedBytes, bytes), e); } }
Source:
public OutputBufferMemoryManager(long maxBufferedBytes, Supplier<LocalMemoryContext> systemMemoryContextSupplier, Executor notificationExecutor) { requireNonNull(systemMemoryContextSupplier, "systemMemoryContextSupplier is null"); checkArgument(maxBufferedBytes > 0, "maxBufferedBytes must be > 0"); this.maxBufferedBytes = maxBufferedBytes; START this.systemMemoryContextSupplier = Suppliers.memoize(() -> systemMemoryContextSupplier.get()); END this.notificationExecutor = requireNonNull(notificationExecutor, "notificationExecutor is null"); notFull = SettableFuture.create(); notFull.set(null); } nit: `Suppliers.memoize(systemMemoryContextSupplier::get)`

Target:
public OutputBufferMemoryManager(long maxBufferedBytes, Supplier<LocalMemoryContext> systemMemoryContextSupplier, Executor notificationExecutor) { requireNonNull(systemMemoryContextSupplier, "systemMemoryContextSupplier is null"); checkArgument(maxBufferedBytes > 0, "maxBufferedBytes must be > 0"); this.maxBufferedBytes = maxBufferedBytes; this.systemMemoryContextSupplier = Suppliers.memoize(systemMemoryContextSupplier::get); this.notificationExecutor = requireNonNull(notificationExecutor, "notificationExecutor is null"); notFull = SettableFuture.create(); notFull.set(null); }
Source:
public void failQuery(QueryId queryId, Throwable cause) { requireNonNull(queryId, "queryId is null"); requireNonNull(cause, "cause is null"); START log.warn(cause, "Fail query %s", queryId); END QueryExecution query = queries.get(queryId); if (query != null) { query.fail(cause); } } Query %s failed. Also, I'm pretty sure we already log failures somewhere? Or if we don't, that there's a good reason for that.

Target:
public void failQuery(QueryId queryId, Throwable cause) { requireNonNull(queryId, "queryId is null"); requireNonNull(cause, "cause is null"); QueryExecution query = queries.get(queryId); if (query != null) { query.fail(cause); } }
Source:
START private static DataSize.Unit valueOfUnit(String unitString) END { for (DataSize.Unit unit : DataSize.Unit.values()) { if (unit.getUnitString().equals(unitString)) { return unit; } } throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "Unit string must be one of [B, kB, MB, GB, TB, PB]"); } static import `DataSize.Unit`

Target:
private static Unit valueOfUnit(String unitString) { for (Unit unit : Unit.values()) { if (unit.getUnitString().equals(unitString)) { return unit; } } throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "Unit string must be one of [B, kB, MB, GB, TB, PB]"); }
Source:
START public static Slice succinctDuration(@SqlType(StandardTypes.DOUBLE) double value, @SqlType(StandardTypes.VARCHAR) Slice unit) END { try { Duration duration = Duration.succinctDuration(value, valueOfTimeUnit(unit.toStringUtf8())); return utf8Slice(duration.toString()); } catch (IllegalArgumentException e) { // When value is negative, NaN, etc. throw new PrestoException(INVALID_FUNCTION_ARGUMENT, e); } } It's good practice to only wrap the relevant code that can throw with try/catch: ``` Duration duration; try { duration = Duration.succinctDuration(value, valueOfTimeUnit(unit.toStringUtf8())); } catch (IllegalArgumentException e) { // When value is negative, NaN, etc. throw new PrestoException(INVALID_FUNCTION_ARGUMENT, e); } return utf8Slice(duration.toString()); ```

Target:
public static Slice succinctDuration(@SqlType(StandardTypes.DOUBLE) double value, @SqlType(StandardTypes.VARCHAR) Slice unit) { Duration duration; try { duration = Duration.succinctDuration(value, valueOfTimeUnit(unit.toStringUtf8())); } catch (IllegalArgumentException e) { // When value is negative, NaN, etc. throw new PrestoException(INVALID_FUNCTION_ARGUMENT, e); } return utf8Slice(duration.toString()); }
Source:
public static Slice hmacMd5( @SqlType(StandardTypes.VARBINARY) Slice slice, @SqlType(StandardTypes.VARBINARY) Slice key) { START return Slices.wrappedBuffer(Hashing.hmacMd5(key.getBytes()).hashBytes(slice.getBytes()).asBytes()); END } static import `wrappedBuffer`

Target:
public static Slice hmacMd5( @SqlType(StandardTypes.VARBINARY) Slice slice, @SqlType(StandardTypes.VARBINARY) Slice key) { return wrappedBuffer(Hashing.hmacMd5(key.getBytes()).hashBytes(slice.getBytes()).asBytes()); }
Source:
private void bindLowMemoryKiller(String name, Class<? extends LowMemoryKiller> clazz) { install(installModuleIf( MemoryManagerConfig.class, config -> name.equals(config.getLowMemoryKillerPolicy()), START moduleBinder -> moduleBinder.bind(LowMemoryKiller.class).to(clazz).in(Scopes.SINGLETON))); END } Nit: could name this variable `binder`

Target:
private void bindLowMemoryKiller(String name, Class<? extends LowMemoryKiller> clazz) { install(installModuleIf( MemoryManagerConfig.class, config -> name.equals(config.getLowMemoryKillerPolicy()), binder -> binder.bind(LowMemoryKiller.class).to(clazz).in(Scopes.SINGLETON))); }
Source:
public void initialize() { if (initialized.compareAndSet(false, true)) { taskStateMachine.addStateChangeListener(new StateChangeListener<TaskState>() { @Override START public void stateChanged(TaskState newState) END { if (newState.isDone()) { executionEndTime.set(DateTime.now()); endNanos.set(System.nanoTime()); } } }); } } can this be turned into lambda?

Target:
private void initialize() { taskStateMachine.addStateChangeListener(newState -> { if (newState.isDone()) { executionEndTime.set(DateTime.now()); endNanos.set(System.nanoTime()); } }); }
Source:
public void initialize() { if (initialized.compareAndSet(false, true)) { START taskStateMachine.addStateChangeListener(newState -> { END if (newState.isDone()) { executionEndTime.set(DateTime.now()); endNanos.set(System.nanoTime()); } }); } } There is a better way to do this. You make the constructor and the initialize method private, and then add a factory method that call the constructor and the initialize. This makes the state tracking simple.

Target:
private void initialize() { taskStateMachine.addStateChangeListener(newState -> { if (newState.isDone()) { executionEndTime.set(DateTime.now()); endNanos.set(System.nanoTime()); } }); }
Source:
void fail(Throwable e) { // The error must be recorded before setting the finish marker to make sure // isFinished will observe failure instead of successful completion. // Only record the first error message. if (setIf(stateReference, State.failed(e), state -> state.getKind() == INITIAL)) { // Stop the split loader before finishing the queue. // Once the queue is finished, it will always return a completed future to avoid blocking any caller. // This could lead to a short period of busy loop in splitLoader (although unlikely in general setup). splitLoader.stop(); queues.finish(); } START checkState(stateReference.get().getKind() == FAILED, END "Another thread raced to complete this split source before failure info is recorded"); } what about timeout, close, or limit

Target:
void fail(Throwable e) { // The error must be recorded before setting the finish marker to make sure // isFinished will observe failure instead of successful completion. // Only record the first error message. if (setIf(stateReference, State.failed(e), state -> state.getKind() == INITIAL)) { // Stop the split loader before finishing the queue. // Once the queue is finished, it will always return a completed future to avoid blocking any caller. // This could lead to a short period of busy loop in splitLoader (although unlikely in general setup). splitLoader.stop(); queues.finish(); } }
Source:
START public Ordering(String field, SortItem.Ordering sortOrder, SortItem.NullOrdering nullOrder) END { this.field = field; this.sortOrder = sortOrder; this.nullOrder = nullOrder; } private? Since there is a factory method below

Target:
private Ordering(String field, SortItem.Ordering sortOrder, SortItem.NullOrdering nullOrder) { this.field = field; this.sortOrder = sortOrder; this.nullOrder = nullOrder; }
Source:
public String toString() { return toStringHelper(this) START .omitNullValues() END .add("filter", filter) .toString(); } there are no null values to omit

Target:
public String toString() { return toStringHelper(this) .add("filter", filter) .toString(); }
Source:
START public synchronized ListenableFuture<Supplier<PagesSpatialIndex>> createPagesSpatialIndex() END { activeProbeOperators.retain(); if (pagesSpatialIndex != null) { return immediateFuture(pagesSpatialIndex); } SettableFuture<Supplier<PagesSpatialIndex>> future = SettableFuture.create(); pagesSpatialIndexFutures.add(future); return future; } as i noted in the operator, this could return `ListenableFuture<PagesSpatialIndex>`

Target:
public synchronized ListenableFuture<PagesSpatialIndex> createPagesSpatialIndex() { activeProbeOperators.retain(); if (pagesSpatialIndex != null) { return immediateFuture(pagesSpatialIndex.get()); } SettableFuture<PagesSpatialIndex> future = SettableFuture.create(); pagesSpatialIndexFutures.add(future); return future; }
Source:
public long getSizeInBytes() { // channels is a List created with ImmutableList#copyOf. // Each element of the List is an ObjectArrayList<Block>. // Hence, the memory used by channels is estimated as // <header-size-of-ImmutableList> + // <instance-size-of-ObjectArrayList> * <length-of-outer-list> + // <sum-of-all-Blocks> START return INSTANCE_SIZE + IMMUTABLE_LIST_HEADER_SIZE + OBJECT_ARRAY_LIST_INSTANCE_SIZE * channels.size() + END channels.stream() .flatMap(List::stream) .mapToLong(Block::getRetainedSizeInBytes) .sum(); } You can format this as below to categorize different types of overhead. ``` return INSTANCE_SIZE + IMMUTABLE_LIST_HEADER_SIZE + OBJECT_ARRAY_LIST_INSTANCE_SIZE * channels.size() + channels.stream() .flatMap(List::stream) .mapToLong(Block::getRetainedSizeInBytes) .sum(); ```

Target:
public long getSizeInBytes() { return INSTANCE_SIZE + channels.stream() .flatMap(List::stream) .mapToLong(Block::getRetainedSizeInBytes) .sum(); }
Source:
public PagesSpatialIndex get() { if (rtree.isEmpty()) { return EMPTY_INDEX; } START else { END return new PagesRTreeIndex(session, addresses, types, outputChannels, channels, rtree, spatialRelationshipTest, filterFunctionFactory); } } `else` not needed.

Target:
public PagesSpatialIndex get() { if (rtree.isEmpty()) { return EMPTY_INDEX; } return new PagesRTreeIndex(session, addresses, types, outputChannels, channels, rtree, spatialRelationshipTest, filterFunctionFactory); }
Source:
private long computeMemorySizeInBytes(AbstractNode root) { if (root.getLevel() == 0) { return ABSTRACT_NODE_INSTANCE_SIZE + ENVELOPE_INSTANCE_SIZE + root.getChildBoundables().stream().mapToLong(child -> computeMemorySizeInBytes((ItemBoundable) child)).sum(); } START else { END return ABSTRACT_NODE_INSTANCE_SIZE + ENVELOPE_INSTANCE_SIZE + root.getChildBoundables().stream().mapToLong(child -> computeMemorySizeInBytes((AbstractNode) child)).sum(); } } `else` not needed.

Target:
private long computeMemorySizeInBytes(AbstractNode root) { if (root.getLevel() == 0) { return ABSTRACT_NODE_INSTANCE_SIZE + ENVELOPE_INSTANCE_SIZE + root.getChildBoundables().stream().mapToLong(child -> computeMemorySizeInBytes((ItemBoundable) child)).sum(); } return ABSTRACT_NODE_INSTANCE_SIZE + ENVELOPE_INSTANCE_SIZE + root.getChildBoundables().stream().mapToLong(child -> computeMemorySizeInBytes((AbstractNode) child)).sum(); }
Source:
public int getDay(Type type, Block block, int position) { if (type.equals(DATE)) { return toIntExact(DATE.getLong(block, position)); } if (type.equals(TIMESTAMP)) { START long millis = block.getLong(position, 0); END long local = timeZone.convertUTCToLocal(millis); long days = MILLISECONDS.toDays(local); return toIntExact(days); } throw new IllegalArgumentException("Wrong type for temporal column: " + type); } This is wrong. You should never read from blocks directly. Always use `Type` to access the block, as types own the data representation within a block.

Target:
public int getDay(Type type, Block block, int position) { if (type.equals(DATE)) { return toIntExact(DATE.getLong(block, position)); } if (type.equals(TIMESTAMP)) { long millis = TIMESTAMP.getLong(block, position); long local = timeZone.convertUTCToLocal(millis); long days = MILLISECONDS.toDays(local); return toIntExact(days); } throw new IllegalArgumentException("Wrong type for temporal column: " + type); }
Source:
public ConnectorTableMetadata getTableMetadata(ConnectorSession session, ConnectorTableHandle table) { ElasticsearchTableHandle handle = checkType(table, ElasticsearchTableHandle.class, "table"); START checkArgument(handle.getConnectorId().equals(connectorId), "tableHandle is not for this connector"); END SchemaTableName tableName = new SchemaTableName(handle.getSchemaName(), handle.getTableName()); return getTableMetadata(session, tableName); } fix `checkArgument ` error message.

Target:
public ConnectorTableMetadata getTableMetadata(ConnectorSession session, ConnectorTableHandle table) { ElasticsearchTableHandle handle = (ElasticsearchTableHandle) table; SchemaTableName tableName = new SchemaTableName(handle.getSchemaName(), handle.getTableName()); return getTableMetadata(tableName); }
Source:
private void checkFieldType(int field, Set<Type> expectedTypes) { Type actual = getType(field); checkArgument(expectedTypes.contains(actual), "Field %s expected type inconsistent with %s", field, actual); StringBuilder builder = new StringBuilder(); for (Type type : expectedTypes) { builder.append(", "); START builder.append(type.getDisplayName()); END } } `result` -> `results`

Target:
private void checkFieldType(int field, Set<Type> expectedTypes) { checkArgument(expectedTypes.contains(getType(field)), "Field %s expected type inconsistent with %s", field, getType(field)); }
Source:
public long getLong(int field) { START checkFieldType(field, ImmutableSet.of(BIGINT, INTEGER)); END return Long.valueOf(String.valueOf(getFieldValue(field))); } why not `(Long) getFieldValue(field);` as you do in other methods?

Target:
public long getLong(int field) { checkFieldType(field, ImmutableSet.of(BIGINT, INTEGER)); return (Integer) getFieldValue(field); }
Source:
START public synchronized void setTableDescriptionSupplier(Supplier<Map<SchemaTableName, ElasticsearchTableDescription>> tableDescriptionSupplier) END { this.tableDescriptionSupplier = Optional.of(requireNonNull(tableDescriptionSupplier, "tableDescriptionSupplier is null")); } pass this in constructor

Target:
public synchronized void setTableDescriptionSupplier(Supplier<Map<SchemaTableName, ElasticsearchTableDescription>> tableDescriptionSupplier) { requireNonNull(tableDescriptionSupplier, "tableDescriptionSupplier is null"); this.tableDescriptionSupplier = Optional.of(tableDescriptionSupplier); }
Source:
ElasticsearchTableDescriptionSupplier(ElasticsearchConnectorConfig config, JsonCodec<ElasticsearchTableDescription> codec) { START this.codec = requireNonNull(codec, "codec is null"); END this.config = requireNonNull(config, "config is null"); } nit: move `config` up as it's the first constructor parameter

Target:
ElasticsearchTableDescriptionSupplier(ElasticsearchConnectorConfig config, JsonCodec<ElasticsearchTableDescription> codec) { this.config = requireNonNull(config, "config is null"); this.codec = requireNonNull(codec, "codec is null"); }
Source:
private static List<File> listFiles(File dir) { START if ((dir != null) && dir.isDirectory()) { END File[] files = dir.listFiles(); if (files != null) { return ImmutableList.copyOf(files); } } return ImmutableList.of(); } unnecessary parens around `dir != null`

Target:
private static List<File> listFiles(File dir) { if (dir != null && dir.isDirectory()) { File[] files = dir.listFiles(); if (files != null) { return ImmutableList.copyOf(files); } } return ImmutableList.of(); }
Source:
START public void cleanUp() END { es.shutdown(); } private?

Target:
private void cleanUp() { es.shutdown(); }
Source:
START public static <T> DataType<T> dataType(String insertType, Type prestoResultType) END { return new DataType<>(insertType, prestoResultType, Object::toString, Function.identity()); } Since this method is good only under certain assumptions (that is: that `toString()` produces good SQL literal), it should be `private`

Target:
private static <T> DataType<T> dataType(String insertType, Type prestoResultType) { return new DataType<>(insertType, prestoResultType, Object::toString, Function.identity()); }
Source:
public TestingConnectorSession(List<PropertyMetadata<?>> properties) { START this("user", Optional.of("test"), UTC_KEY, ENGLISH, System.currentTimeMillis(), properties, ImmutableMap.of(), true); END } Shouldn't the default here (`true`) should be taken from F.C.: `new FeatureConfig().isLegacyTimestamp()`?

Target:
public TestingConnectorSession(List<PropertyMetadata<?>> properties) { this("user", Optional.of("test"), UTC_KEY, ENGLISH, System.currentTimeMillis(), properties, ImmutableMap.of(), false); }
Source:
public void close() { START checkState(initialized.get(), "Driver is not initialized"); END // mark the service for destruction if (!state.compareAndSet(State.ALIVE, State.NEED_DESTRUCTION)) { return; } exclusiveLock.interruptCurrentOwner(); // if we can get the lock, attempt a clean shutdown; otherwise someone else will shutdown tryWithLock(() -> TRUE); } Close is called in cleanup-after-exceptional-condition situations, so it should just do the job. If it is to complain about anything, this should be the last thing it does.

Target:
public void close() { // mark the service for destruction if (!state.compareAndSet(State.ALIVE, State.NEED_DESTRUCTION)) { return; } exclusiveLock.interruptCurrentOwner(); // if we can get the lock, attempt a clean shutdown; otherwise someone else will shutdown tryWithLock(() -> TRUE); }
Source:
START public boolean set(@Nullable V value) END { return super.set(value); } I think this can be private or at least package protected.

Target:
protected boolean set(@Nullable V value) { return super.set(value); }
Source:
public static Boolean varcharIsJsonScalar(@SqlType("varchar(x)") Slice json) { START return isJsonScalar(jsonParse(json)); END } Don't need to call `jsonParse` here.

Target:
public static Boolean varcharIsJsonScalar(@SqlType("varchar(x)") Slice json) { return isJsonScalar(json); }
Source:
public Object geometryToBingTiles(BenchmarkData data) START throws Throwable END { return BingTileFunctions.geometryToBingTiles(data.geometry, data.zoomLevel); } `throws` can be removed (also for the other benchmark method).

Target:
public Object geometryToBingTiles(BenchmarkData data) { return BingTileFunctions.geometryToBingTiles(data.geometry, data.zoomLevel); }
Source:
public void close() { if (client == null) { return; } try { client.close(); } catch (Exception e) { START log.warn("Error closing client", e); END } } Can you change the order of parameters? In airlift it's (e, message).

Target:
public void close() { if (client == null) { return; } try { client.close(); } catch (Exception e) { log.warn(e, "Error closing client"); } client = null; }
Source:
public DefaultThriftService(PrestoThriftService prestoThriftService, HostLocationHandle hostLocationHandle) { START requireNonNull(hostLocationHandle, "hostLocationHandle is null"); END requireNonNull(prestoThriftService, "prestoThriftService is null"); this.hostLocationHandle = hostLocationHandle; this.prestoThriftService = prestoThriftService; } inline with assignments

Target:
public DefaultThriftService(PrestoThriftService prestoThriftService, HostLocationHandle hostLocationHandle) { this.prestoThriftService = requireNonNull(prestoThriftService, "prestoThriftService is null"); this.hostLocationHandle = requireNonNull(hostLocationHandle, "hostLocationHandle is null"); }
Source:
public DefaultThriftService(PrestoThriftService prestoThriftService, HostLocationHandle hostLocationHandle) { START this.hostLocationHandle = requireNonNull(hostLocationHandle, "hostLocationHandle is null"); END this.prestoThriftService = requireNonNull(prestoThriftService, "prestoThriftService is null"); } nit: I'd initialize in the order of parameters - first service, then location.

Target:
public DefaultThriftService(PrestoThriftService prestoThriftService, HostLocationHandle hostLocationHandle) { this.prestoThriftService = requireNonNull(prestoThriftService, "prestoThriftService is null"); this.hostLocationHandle = requireNonNull(hostLocationHandle, "hostLocationHandle is null"); }
Source:
void shutdown() { try { START retryExecutor.shutdownNow(); END } catch (Exception ignore) { } } if(retryExecutor!=null)

Target:
void shutdown() { try { if (retryExecutor != null) { retryExecutor.shutdownNow(); } } catch (Exception ignore) { } }
Source:
public int getEstimatedSizeInBytes() { int result = INSTANCE_SIZE; result += SizeOf.sizeOfObjectArray(addresses.size()); for (HostAddress address : addresses) { START result += HOST_ADDRESS_INSTANCE_SIZE + address.getHostText().length() * Character.BYTES; END } return result; } Add parens

Target:
public int getEstimatedSizeInBytes() { int result = INSTANCE_SIZE; result += sizeOfObjectArray(addresses.size()); for (HostAddress address : addresses) { result += HOST_ADDRESS_INSTANCE_SIZE + address.getHostText().length() * Character.BYTES; } return result; }