blob: a2efa53c6a58c22b4327de1404d27972b262e007 [file] [log] [blame]
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. 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';
class RingBuffer<T> {
RingBuffer(this._bufferSize) {
_buffer = List<T?>.filled(
_bufferSize,
null,
);
}
Iterable<T> call() sync* {
for (int i = _size - 1; i >= 0; --i) {
yield _buffer[(_count - i - 1) % _bufferSize]!;
}
}
/// Inserts a new element into the [RingBuffer].
///
/// Returns the element evicted as a result of adding the new element if the
/// buffer is as max capacity, null otherwise.
T? add(T e) {
if (_buffer.isEmpty) {
return null;
}
T? evicted;
final index = _count % _bufferSize;
if (index < _count) {
evicted = _buffer[index];
}
_buffer[index] = e;
_count++;
return evicted;
}
void resize(int size) {
assert(size >= 0);
if (size == _bufferSize) {
return;
}
final resized = List<T?>.filled(
size,
null,
);
int count = 0;
if (size > 0) {
for (final e in this()) {
resized[count++ % size] = e;
}
}
_count = count;
_bufferSize = size;
_buffer = resized;
}
bool get isTruncated => _count % bufferSize < _count;
int get bufferSize => _bufferSize;
int get _size => min(_count, _bufferSize);
int _bufferSize;
int _count = 0;
late List<T?> _buffer;
}