Skip to content

Commit

Permalink
Refactor and cleanup byte utilities (#7406)
Browse files Browse the repository at this point in the history
  • Loading branch information
kenzieschmoll authored Mar 21, 2024
1 parent fa1760f commit d1df40c
Show file tree
Hide file tree
Showing 27 changed files with 267 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:devtools_app_shared/ui.dart';
import 'package:flutter/material.dart';

import '../../shared/charts/treemap.dart';
import '../../shared/primitives/byte_utils.dart';
import '../../shared/primitives/utils.dart';
import '../../shared/table/table.dart';
import '../../shared/table/table_data.dart';
Expand Down Expand Up @@ -112,11 +113,7 @@ class _SizeColumn extends ColumnData<TreemapNode> {

@override
String getDisplayValue(TreemapNode dataObject) {
return prettyPrintBytes(
dataObject.byteSize,
kbFractionDigits: 1,
includeUnit: true,
)!;
return prettyPrintBytes(dataObject.byteSize, includeUnit: true)!;
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import '../../service/vm_service_wrapper.dart';
import '../../shared/diagnostics/diagnostics_node.dart';
import '../../shared/diagnostics/inspector_service.dart';
import '../../shared/globals.dart';
import '../../shared/primitives/byte_utils.dart';
import '../../shared/primitives/message_bus.dart';
import '../../shared/primitives/utils.dart';
import '../../shared/ui/filter.dart';
Expand Down Expand Up @@ -348,8 +349,8 @@ class LoggingController extends DisposableController

final String summary = '${isolateRef['name']} • '
'${e.json!['reason']} collection in $time ms • '
'${printMB(usedBytes, includeUnit: true)} used of '
'${printMB(capacityBytes, includeUnit: true)}';
'${printBytes(usedBytes, unit: ByteUnit.mb, includeUnit: true)} used of '
'${printBytes(capacityBytes, unit: ByteUnit.mb, includeUnit: true)}';

final event = <String, Object>{
'reason': e.json!['reason'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:devtools_shared/devtools_shared.dart';
import 'package:flutter/material.dart';

import '../../../../shared/charts/chart_trace.dart';
import '../../../../shared/primitives/byte_utils.dart';
import '../../../../shared/primitives/utils.dart';
import '../../framework/connected/memory_controller.dart';
import 'memory_android_chart.dart';
Expand Down Expand Up @@ -380,7 +381,6 @@ class ChartsValues {

String? formatNumeric(num? number) => prettyPrintBytes(
number,
kbFractionDigits: 1,
mbFractionDigits: 2,
includeUnit: true,
roundingPoint: 0.7,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart';

import '../../../../../../shared/analytics/analytics.dart' as ga;
import '../../../../../../shared/analytics/constants.dart' as gac;
import '../../../../../../shared/primitives/byte_utils.dart';
import '../../../../../../shared/primitives/utils.dart';
import '../../../../../../shared/table/table.dart';
import '../../../../../../shared/table/table_data.dart';
Expand Down Expand Up @@ -66,11 +67,8 @@ class _ShallowSizeColumn extends ColumnData<StatsByPathEntry> {
bool get numeric => true;

@override
String getDisplayValue(StatsByPathEntry record) => prettyPrintBytes(
getValue(record),
includeUnit: true,
kbFractionDigits: 1,
)!;
String getDisplayValue(StatsByPathEntry record) =>
prettyPrintBytes(getValue(record), includeUnit: true)!;
}

class _RetainedSizeColumn extends ColumnData<StatsByPathEntry> {
Expand All @@ -89,11 +87,8 @@ class _RetainedSizeColumn extends ColumnData<StatsByPathEntry> {
bool get numeric => true;

@override
String getDisplayValue(StatsByPathEntry record) => prettyPrintBytes(
getValue(record),
includeUnit: true,
kbFractionDigits: 1,
)!;
String getDisplayValue(StatsByPathEntry record) =>
prettyPrintBytes(getValue(record), includeUnit: true)!;
}

class _RetainingPathTableColumns {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
import '../../../../../shared/analytics/analytics.dart' as ga;
import '../../../../../shared/analytics/constants.dart' as gac;
import '../../../../../shared/globals.dart';
import '../../../../../shared/primitives/byte_utils.dart';
import '../../../../../shared/primitives/utils.dart';
import '../../../../../shared/table/table.dart';
import '../../../../../shared/table/table_data.dart';
Expand Down Expand Up @@ -125,11 +126,8 @@ class _ShallowSizeColumn extends ColumnData<SingleClassStats> {
bool get numeric => true;

@override
String getDisplayValue(SingleClassStats classStats) => prettyPrintBytes(
getValue(classStats),
includeUnit: true,
kbFractionDigits: 1,
)!;
String getDisplayValue(SingleClassStats classStats) =>
prettyPrintBytes(getValue(classStats), includeUnit: true)!;
}

class _RetainedSizeColumn extends ColumnData<SingleClassStats> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import '../../../../../shared/analytics/analytics.dart' as ga;
import '../../../../../shared/analytics/constants.dart' as gac;
import '../../../../../shared/common_widgets.dart';
import '../../../../../shared/memory/simple_items.dart';
import '../../../../../shared/primitives/utils.dart';
import '../../../../../shared/primitives/byte_utils.dart';
import '../../../shared/primitives/simple_elements.dart';
import '../controller/diff_pane_controller.dart';
import '../controller/item_controller.dart';
Expand Down Expand Up @@ -139,7 +139,8 @@ class _SnapshotSizeView extends StatelessWidget {
return Text(
items.entries
.map<String>(
(e) => '${e.key}: ${prettyPrintBytes(e.value, includeUnit: true)}',
(e) => '${e.key}: '
'${prettyPrintBytes(e.value, includeUnit: true, kbFractionDigits: 0)}',
)
// TODO(polina-c): consider using vertical divider instead of text.
.join(' | '),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import '../../../../../shared/analytics/analytics.dart' as ga;
import '../../../../../shared/analytics/constants.dart' as gac;
import '../../../../../shared/common_widgets.dart';
import '../../../../../shared/dialogs.dart';
import '../../../../../shared/primitives/byte_utils.dart';
import '../../../../../shared/primitives/utils.dart';
import '../controller/diff_pane_controller.dart';
import '../controller/item_controller.dart';
Expand Down Expand Up @@ -174,11 +175,7 @@ class SnapshotListTitle extends StatelessWidget {
trailing.addAll([
if (theItem.totalSize != null)
Text(
prettyPrintBytes(
theItem.totalSize,
includeUnit: true,
kbFractionDigits: 1,
)!,
prettyPrintBytes(theItem.totalSize, includeUnit: true)!,
),
Padding(
padding: const EdgeInsets.only(left: ContextMenuButton.densePadding),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '../../../../shared/analytics/analytics.dart' as ga;
import '../../../../shared/analytics/constants.dart' as gac;
import '../../../../shared/common_widgets.dart';
import '../../../../shared/globals.dart';
import '../../../../shared/primitives/byte_utils.dart';
import '../../../../shared/primitives/simple_items.dart';
import '../../../../shared/primitives/utils.dart';
import '../../../../shared/table/table.dart';
Expand Down Expand Up @@ -228,12 +229,7 @@ class _FieldSizeColumn extends ColumnData<ProfileRecord> {

@override
String getDisplayValue(ProfileRecord dataObject) =>
prettyPrintBytes(
getValue(dataObject),
includeUnit: true,
kbFractionDigits: 1,
) ??
'';
prettyPrintBytes(getValue(dataObject), includeUnit: true) ?? '';

@override
String getTooltip(ProfileRecord dataObject) => '${getValue(dataObject)} B';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:image/image.dart' as image;
import '../../shared/common_widgets.dart';
import '../../shared/http/http.dart';
import '../../shared/http/http_request_data.dart';
import '../../shared/primitives/byte_utils.dart';
import '../../shared/primitives/utils.dart';
import '../../shared/ui/colors.dart';
import 'network_controller.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:vm_service/vm_service.dart';

import '../../../shared/analytics/constants.dart' as gac;
import '../../../shared/common_widgets.dart';
import '../../../shared/primitives/byte_utils.dart';
import '../../../shared/primitives/utils.dart';
import '../../../shared/table/table.dart';
import '../../../shared/table/table_data.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import 'package:vm_service/vm_service.dart';
import '../../shared/analytics/constants.dart' as gac;
import '../../shared/common_widgets.dart';
import '../../shared/globals.dart';
import '../../shared/primitives/byte_utils.dart';
import '../../shared/primitives/utils.dart';
import '../../shared/tree.dart';
import '../debugger/codeview.dart';
Expand Down Expand Up @@ -237,7 +238,6 @@ class RequestableSizeWidget extends StatelessWidget {
: prettyPrintBytes(
int.parse(size.valueAsString!),
includeUnit: true,
kbFractionDigits: 1,
maxBytes: 512,
)!,
),
Expand Down Expand Up @@ -855,7 +855,6 @@ MapEntry<String, WidgetBuilder> shallowSizeRowBuilder(VmObject object) {
prettyPrintBytes(
object.obj.size ?? 0,
includeUnit: true,
kbFractionDigits: 1,
maxBytes: 512,
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:vm_service/vm_service.dart';

import '../../../shared/analytics/constants.dart' as gac;
import '../../../shared/common_widgets.dart';
import '../../../shared/primitives/byte_utils.dart';
import '../../../shared/primitives/utils.dart';
import '../../../shared/table/table.dart';
import '../../../shared/table/table_data.dart';
Expand Down
4 changes: 2 additions & 2 deletions packages/devtools_app/lib/src/shared/charts/treemap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import 'package:flutter/material.dart';
import 'package:logging/logging.dart';

import '../common_widgets.dart';
import '../primitives/byte_utils.dart';
import '../primitives/trees.dart';
import '../primitives/utils.dart';
import '../ui/colors.dart';

enum PivotType { pivotByMiddle, pivotBySize }
Expand Down Expand Up @@ -757,7 +757,7 @@ class TreemapNode extends TreeNode<TreemapNode> {
String prettyByteSize() {
// Negative sign isn't explicitly added since a regular print of a negative number includes it.
final plusSign = showDiff && byteSize > 0 ? '+' : '';
return '$plusSign${prettyPrintBytes(byteSize, kbFractionDigits: 1, includeUnit: true)}';
return '$plusSign${prettyPrintBytes(byteSize, includeUnit: true)}';
}

/// Returns a list of [TreemapNode] in the path from root node to [this].
Expand Down
117 changes: 117 additions & 0 deletions packages/devtools_app/lib/src/shared/primitives/byte_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:math';

String? prettyPrintBytes(
num? bytes, {
int kbFractionDigits = 1,
int mbFractionDigits = 1,
int gbFractionDigits = 1,
bool includeUnit = false,
num roundingPoint = 1.0,
int maxBytes = 52,
}) {
if (bytes == null) {
return null;
}
// TODO(kenz): Generalize to handle different kbFractionDigits.
// Ensure a small number of bytes does not print as 0 KB.
// If bytes >= maxBytes and kbFractionDigits == 1, it will start rounding to
// 0.1 KB.
if (bytes.abs() < maxBytes && kbFractionDigits == 1) {
var output = bytes.toString();
if (includeUnit) {
output += ' B';
}
return output;
}
final sizeInMB = convertBytes(bytes.abs(), to: ByteUnit.mb);
final sizeInGB = convertBytes(bytes.abs(), to: ByteUnit.gb);

ByteUnit printUnit;
if (sizeInGB >= roundingPoint) {
printUnit = ByteUnit.gb;
} else if (sizeInMB >= roundingPoint) {
printUnit = ByteUnit.mb;
} else {
printUnit = ByteUnit.kb;
}

final fractionDigits = switch (printUnit) {
ByteUnit.kb => kbFractionDigits,
ByteUnit.mb => mbFractionDigits,
ByteUnit.gb || _ => gbFractionDigits,
};

return printBytes(
bytes,
unit: printUnit,
fractionDigits: fractionDigits,
includeUnit: includeUnit,
);
}

String printBytes(
num bytes, {
ByteUnit unit = ByteUnit.byte,
int fractionDigits = 1,
bool includeUnit = false,
}) {
if (unit == ByteUnit.kb) {
// We add ((1024/2)-1) to the value before formatting so that a non-zero
// byte value doesn't round down to 0. If showing decimal points, let it
// round normally.
// TODO(peterdjlee): Round up to the respective digit when fractionDigits > 0.
bytes = fractionDigits == 0 ? bytes + 511 : bytes;
}
final bytesDisplay =
convertBytes(bytes, to: unit).toStringAsFixed(fractionDigits);
final unitSuffix = includeUnit ? ' ${unit.display}' : '';
return '$bytesDisplay$unitSuffix';
}

num convertBytes(
num value, {
ByteUnit from = ByteUnit.byte,
required ByteUnit to,
}) {
final multiplier = to.multiplierCount - from.multiplierCount;
final multiplierValue = pow(ByteUnit.unitMultiplier, multiplier.abs());

if (multiplier > 0) {
// A positive multiplier indicates that we are going from a smaller unit to
// a larger unit (e.g. from bytes to GB).
return value / multiplierValue;
} else if (multiplier < 0) {
// A positive multiplier indicates that we are going from a larger unit to
// a smaller unit (e.g. from GB to bytes).
return value * multiplierValue;
} else {
return value;
}
}

enum ByteUnit {
byte(multiplierCount: 0, display: 'bytes'),
kb(multiplierCount: 1),
mb(multiplierCount: 2),
gb(multiplierCount: 3);

const ByteUnit({required this.multiplierCount, String? display})
: _display = display;

static const unitMultiplier = 1024.0;

/// The number of times this unit should be multiplied or divided by
/// [unitMultiplier] to convert between units.
///
/// [ByteUnit.byte] is the baseline, with zero multipliers. All other units
/// have a value for [multiplierCount] that is relative to [ByteUnit.byte].
final int multiplierCount;

final String? _display;

String get display => _display ?? name.toUpperCase();
}
Loading

0 comments on commit d1df40c

Please sign in to comment.