RingBuffer.vala 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. namespace Invercargill.DataStructures {
  2. public class RingBuffer<T> : Enumerable<T>, Lot<T>, ReadOnlyAddressable<T>, Addressable<T> {
  3. private T[] array;
  4. private SafeReadFunc<T>? safe_read;
  5. private SafeWriteFunc<T>? safe_write;
  6. public override Tracker<T> get_tracker () {
  7. int pos = 0;
  8. return new LambdaTracker<T> (() => array.length > 0, () => safe_read(array, pos++ % array.length));
  9. }
  10. public override uint? peek_count () {
  11. return null; // Technically infinate if iterated
  12. }
  13. public override EnumerableInfo get_info () {
  14. return new EnumerableInfo.infer_ultimate(this, EnumerableCategory.IN_MEMORY);
  15. }
  16. public override uint length { get { return array.length; }}
  17. public RingBuffer(uint size) {
  18. array = new T[size];
  19. safe_read = get_safe_read_function_for<T>();
  20. if(safe_read == null) {
  21. safe_read = (a, i) => a[i];
  22. }
  23. safe_write = get_safe_write_function_for<T>();
  24. if(safe_write == null) {
  25. safe_write = (a, i, v) => a[i] = v;
  26. }
  27. }
  28. public Enumerable<T> once() {
  29. return take(array.length);
  30. }
  31. internal RingBuffer.take_array(owned T[] array) {
  32. this.array = (owned)array;
  33. safe_read = get_safe_read_function_for<T>();
  34. if(safe_read == null) {
  35. safe_read = (a, i) => a[i];
  36. }
  37. safe_write = get_safe_write_function_for<T>();
  38. if(safe_write == null) {
  39. safe_write = (a, i, v) => a[i] = v;
  40. }
  41. }
  42. public new void set (uint index, T item) throws IndexError {
  43. var real_index = index % array.length;
  44. safe_write(array, real_index, item);
  45. }
  46. public new T get (uint index) {
  47. var real_index = index % array.length;
  48. return safe_read(array, real_index);
  49. }
  50. public bool try_get (uint index, out T value) {
  51. try {
  52. value = get(index);
  53. return true;
  54. }
  55. catch {
  56. value = null;
  57. return false;
  58. }
  59. }
  60. public uint? first_index_of (Invercargill.PredicateDelegate<T> predicate) {
  61. var i = 0;
  62. foreach (var item in this) {
  63. if(predicate(item)) {
  64. return i;
  65. }
  66. i++;
  67. }
  68. return null;
  69. }
  70. public override uint count(PredicateDelegate<T>? predicate = null) {
  71. if(predicate == null) {
  72. return array.length;
  73. }
  74. return base.take(array.length).count(predicate);
  75. }
  76. }
  77. }