mirror of
https://github.com/mikkelam/fast-cli.git
synced 2025-12-16 20:04:05 +00:00
refactor use of bandwidthmeter
This commit is contained in:
parent
3570f5d5b7
commit
34ed84f50f
2 changed files with 26 additions and 105 deletions
|
|
@ -20,56 +20,39 @@ pub const SpeedUnit = enum {
|
|||
pub const SpeedMeasurement = struct {
|
||||
value: f64,
|
||||
unit: SpeedUnit,
|
||||
|
||||
pub fn format(self: SpeedMeasurement, allocator: std.mem.Allocator) ![]u8 {
|
||||
return std.fmt.allocPrint(allocator, "{d:.1} {s}", .{ self.value, self.unit.toString() });
|
||||
}
|
||||
};
|
||||
|
||||
pub const BandwidthMeter = struct {
|
||||
bytes_transferred: u64 = 0,
|
||||
timer: std.time.Timer = undefined,
|
||||
started: bool = false,
|
||||
_bytes_transferred: u64 = 0,
|
||||
_timer: std.time.Timer = undefined,
|
||||
_started: bool = false,
|
||||
|
||||
pub fn init() BandwidthMeter {
|
||||
return .{};
|
||||
}
|
||||
|
||||
pub fn start(self: *BandwidthMeter) !void {
|
||||
self.timer = try std.time.Timer.start();
|
||||
self.started = true;
|
||||
self._timer = try std.time.Timer.start();
|
||||
self._started = true;
|
||||
}
|
||||
|
||||
pub fn update_total(self: *BandwidthMeter, total_bytes: u64) void {
|
||||
assert(self._started);
|
||||
self._bytes_transferred = total_bytes;
|
||||
}
|
||||
|
||||
pub fn record_bytes(self: *BandwidthMeter, byte_count: usize) void {
|
||||
assert(self.started);
|
||||
self.bytes_transferred += byte_count;
|
||||
}
|
||||
|
||||
pub fn record_data(self: *BandwidthMeter, data: []const u8) usize {
|
||||
assert(self.started);
|
||||
const n = data.len;
|
||||
self.bytes_transferred += n;
|
||||
return n;
|
||||
assert(self._started);
|
||||
self._bytes_transferred += byte_count;
|
||||
}
|
||||
|
||||
pub fn bandwidth(self: *BandwidthMeter) f64 {
|
||||
if (!self.started) return 0;
|
||||
if (!self._started) return 0;
|
||||
|
||||
const delta_nanos = self.timer.read();
|
||||
const delta_nanos = self._timer.read();
|
||||
const delta_secs = @as(f64, @floatFromInt(delta_nanos)) / std.time.ns_per_s;
|
||||
|
||||
return @as(f64, @floatFromInt(self.bytes_transferred)) / delta_secs;
|
||||
}
|
||||
|
||||
/// Get the total bytes transferred (uploaded or downloaded)
|
||||
pub fn bytesTransferred(self: *const BandwidthMeter) u64 {
|
||||
return self.bytes_transferred;
|
||||
}
|
||||
|
||||
/// Get the duration since start in nanoseconds
|
||||
pub fn duration(self: *BandwidthMeter) !u64 {
|
||||
if (!self.started) return error.NotStarted;
|
||||
return self.timer.read();
|
||||
return @as(f64, @floatFromInt(self._bytes_transferred)) / delta_secs;
|
||||
}
|
||||
|
||||
/// Get bandwidth with automatic unit selection for optimal readability
|
||||
|
|
@ -94,47 +77,20 @@ pub const BandwidthMeter = struct {
|
|||
return SpeedMeasurement{ .value = speed_bits_per_sec, .unit = .bps };
|
||||
}
|
||||
}
|
||||
|
||||
/// Get bandwidth in Mbps (commonly used for internet speeds)
|
||||
pub fn bandwidthMbps(self: *BandwidthMeter) f64 {
|
||||
return self.bandwidth() / 1_000_000;
|
||||
}
|
||||
|
||||
/// Format bandwidth as human-readable string with appropriate units
|
||||
pub fn formatBandwidth(self: *BandwidthMeter, allocator: std.mem.Allocator) ![]u8 {
|
||||
const measurement = self.bandwidthWithUnits();
|
||||
return measurement.format(allocator);
|
||||
}
|
||||
};
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
test "BandwidthMeter init" {
|
||||
const meter = BandwidthMeter.init();
|
||||
try testing.expect(!meter.started);
|
||||
try testing.expectEqual(@as(u64, 0), meter.bytes_transferred);
|
||||
try testing.expect(!meter._started);
|
||||
try testing.expectEqual(@as(u64, 0), meter._bytes_transferred);
|
||||
}
|
||||
|
||||
test "BandwidthMeter start" {
|
||||
var meter = BandwidthMeter.init();
|
||||
try meter.start();
|
||||
try testing.expect(meter.started);
|
||||
}
|
||||
|
||||
test "BandwidthMeter record_data and bytesTransferred" {
|
||||
var meter = BandwidthMeter.init();
|
||||
try meter.start();
|
||||
|
||||
const data = "hello world";
|
||||
const recorded = meter.record_data(data);
|
||||
|
||||
try testing.expectEqual(data.len, recorded);
|
||||
try testing.expectEqual(@as(u64, data.len), meter.bytesTransferred());
|
||||
|
||||
// Record more data
|
||||
const more_data = "test";
|
||||
_ = meter.record_data(more_data);
|
||||
try testing.expectEqual(@as(u64, data.len + more_data.len), meter.bytesTransferred());
|
||||
try testing.expect(meter._started);
|
||||
}
|
||||
|
||||
test "BandwidthMeter record_bytes" {
|
||||
|
|
@ -142,10 +98,11 @@ test "BandwidthMeter record_bytes" {
|
|||
try meter.start();
|
||||
|
||||
meter.record_bytes(1000);
|
||||
try testing.expectEqual(@as(u64, 1000), meter.bytesTransferred());
|
||||
|
||||
meter.record_bytes(500);
|
||||
try testing.expectEqual(@as(u64, 1500), meter.bytesTransferred());
|
||||
|
||||
// Just test that bandwidth calculation works
|
||||
const bw = meter.bandwidth();
|
||||
try testing.expect(bw >= 0);
|
||||
}
|
||||
|
||||
test "BandwidthMeter bandwidth calculation" {
|
||||
|
|
@ -161,24 +118,11 @@ test "BandwidthMeter bandwidth calculation" {
|
|||
try testing.expect(bw > 0);
|
||||
}
|
||||
|
||||
test "BandwidthMeter duration" {
|
||||
var meter = BandwidthMeter.init();
|
||||
try meter.start();
|
||||
|
||||
std.time.sleep(std.time.ns_per_ms * 10); // 10ms
|
||||
|
||||
const dur = try meter.duration();
|
||||
try testing.expect(dur >= std.time.ns_per_ms * 5); // Allow more variance
|
||||
}
|
||||
|
||||
test "BandwidthMeter not started errors" {
|
||||
var meter = BandwidthMeter.init();
|
||||
|
||||
// Should return 0 bandwidth when not started
|
||||
try testing.expectEqual(@as(f64, 0), meter.bandwidth());
|
||||
|
||||
// Should error when getting duration before start
|
||||
try testing.expectError(error.NotStarted, meter.duration());
|
||||
}
|
||||
|
||||
test "BandwidthMeter unit conversion" {
|
||||
|
|
@ -186,8 +130,8 @@ test "BandwidthMeter unit conversion" {
|
|||
try meter.start();
|
||||
|
||||
// Test different speed ranges
|
||||
meter.bytes_transferred = 1000;
|
||||
meter.timer = try std.time.Timer.start();
|
||||
meter._bytes_transferred = 1000;
|
||||
meter._timer = try std.time.Timer.start();
|
||||
std.time.sleep(std.time.ns_per_s); // 1 second
|
||||
|
||||
const measurement = meter.bandwidthWithUnits();
|
||||
|
|
@ -196,26 +140,3 @@ test "BandwidthMeter unit conversion" {
|
|||
try testing.expect(measurement.value > 0);
|
||||
try testing.expect(measurement.unit != .gbps); // Shouldn't be gigabits for small test
|
||||
}
|
||||
|
||||
test "BandwidthMeter Mbps conversion" {
|
||||
var meter = BandwidthMeter.init();
|
||||
try meter.start();
|
||||
|
||||
meter.bytes_transferred = 1_000_000; // 1MB
|
||||
meter.timer = try std.time.Timer.start();
|
||||
std.time.sleep(std.time.ns_per_s); // 1 second
|
||||
|
||||
const mbps = meter.bandwidthMbps();
|
||||
try testing.expect(mbps > 0);
|
||||
}
|
||||
|
||||
test "SpeedMeasurement format" {
|
||||
const measurement = SpeedMeasurement{ .value = 100.5, .unit = .mbps };
|
||||
const allocator = testing.allocator;
|
||||
|
||||
const formatted = try measurement.format(allocator);
|
||||
defer allocator.free(formatted);
|
||||
|
||||
try testing.expect(std.mem.indexOf(u8, formatted, "100.5") != null);
|
||||
try testing.expect(std.mem.indexOf(u8, formatted, "Mbps") != null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ pub const HTTPSpeedTester = struct {
|
|||
|
||||
if (has_progress) {
|
||||
const current_bytes = worker_manager.getCurrentDownloadBytes(workers);
|
||||
bandwidth_meter.bytes_transferred = current_bytes;
|
||||
bandwidth_meter.update_total(current_bytes);
|
||||
const measurement = bandwidth_meter.bandwidthWithUnits();
|
||||
progress_callback.call(measurement);
|
||||
}
|
||||
|
|
@ -279,7 +279,7 @@ pub const HTTPSpeedTester = struct {
|
|||
|
||||
if (has_progress) {
|
||||
const current_bytes = worker_manager.getCurrentUploadBytes(workers);
|
||||
bandwidth_meter.bytes_transferred = current_bytes;
|
||||
bandwidth_meter.update_total(current_bytes);
|
||||
const measurement = bandwidth_meter.bandwidthWithUnits();
|
||||
progress_callback.call(measurement);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue