52 lines
1.4 KiB
Dart
52 lines
1.4 KiB
Dart
import '../proto/messages.pb.dart';
|
|
|
|
/// Fixed-capacity ring buffer of log entries. Same semantics as PacketBuffer
|
|
/// but tuned for log throughput (much lower than data).
|
|
class LogBuffer {
|
|
LogBuffer({required this.capacity}) : _storage = List.filled(capacity, null);
|
|
|
|
int capacity;
|
|
List<LogPacket?> _storage;
|
|
int _head = 0;
|
|
int _length = 0;
|
|
|
|
int get length => _length;
|
|
bool get isEmpty => _length == 0;
|
|
|
|
void add(LogPacket entry) {
|
|
_storage[_head] = entry;
|
|
_head = (_head + 1) % capacity;
|
|
if (_length < capacity) _length++;
|
|
}
|
|
|
|
void clear() {
|
|
_head = 0;
|
|
_length = 0;
|
|
for (var i = 0; i < _storage.length; i++) {
|
|
_storage[i] = null;
|
|
}
|
|
}
|
|
|
|
void resize(int newCapacity) {
|
|
if (newCapacity == capacity) return;
|
|
final preserve = newCapacity < _length ? newCapacity : _length;
|
|
final newStorage = List<LogPacket?>.filled(newCapacity, null);
|
|
final start = (_head - preserve + capacity) % capacity;
|
|
for (var i = 0; i < preserve; i++) {
|
|
newStorage[i] = _storage[(start + i) % capacity];
|
|
}
|
|
_storage = newStorage;
|
|
capacity = newCapacity;
|
|
_head = preserve % newCapacity;
|
|
_length = preserve;
|
|
}
|
|
|
|
/// Iterate from oldest to newest.
|
|
Iterable<LogPacket> iterate() sync* {
|
|
if (_length == 0) return;
|
|
final start = (_head - _length + capacity) % capacity;
|
|
for (var i = 0; i < _length; i++) {
|
|
yield _storage[(start + i) % capacity]!;
|
|
}
|
|
}
|
|
} |