Series.vala 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. namespace Invercargill {
  2. public class Series<T> : Enumerable<T> {
  3. internal class SeriesItem<T> {
  4. public SeriesItem next = null;
  5. public T value;
  6. public SeriesItem(T value) {
  7. this.value = value;
  8. }
  9. // Carefully unlink series items when destructed.
  10. // Very large series sometimes cause a segfault without this
  11. ~SeriesItem() {
  12. var n = next;
  13. while(n != null) {
  14. var c = n;
  15. n = n.next;
  16. c.next = null;
  17. }
  18. }
  19. }
  20. internal SeriesItem<T> root;
  21. internal SeriesItem<T> end;
  22. private int n_items = 0;
  23. public Series() {}
  24. public override Tracker<T> get_tracker() {
  25. var current = root;
  26. return new LambdaTracker<T>(
  27. () => current != null,
  28. () => {
  29. var val = current.value;
  30. current = current.next;
  31. return val;
  32. });
  33. }
  34. public override T[] to_array () {
  35. var arr = new T[n_items];
  36. var count = 0;
  37. iterate(i => {
  38. arr[count] = i;
  39. count++;
  40. });
  41. return arr;
  42. }
  43. public void add(T item) {
  44. lock(root) {
  45. n_items++;
  46. var si = new SeriesItem<T>(item);
  47. if(root == null) {
  48. root = si;
  49. end = si;
  50. return;
  51. }
  52. end.next = si;
  53. end = si;
  54. }
  55. }
  56. public void add_all(Enumerable<T> items) {
  57. items.iterate(i => add(i));
  58. }
  59. public override int count() {
  60. return n_items;
  61. }
  62. }
  63. }