using System; using System.Collections.Generic; using System.Linq; namespace Advanced.Algorithms.Distributed; /// /// Cicular queue aka Ring Buffer using fixed size array. /// public class CircularQueue { //points to the index new element should be inserted private int end; private readonly T[] queue; //points to the index of next element to be deleted private int start; public CircularQueue(int size) { queue = new T[size]; } public int Count { get; private set; } /// /// Note: When buffer overflows oldest data will be erased. /// Time complexity: O(1) /// public T Enqueue(T data) { var deleted = default(T); //wrap around removing oldest element if (end > queue.Length - 1) { end = 0; if (start == 0) { deleted = queue[start]; start++; } } //when end meets start after wraping around if (end == start && Count > 1) { deleted = queue[start]; start++; } queue[end] = data; end++; if (Count < queue.Length) Count++; return deleted; } /// /// Time complexity: O(n). /// /// Deleted items. public IEnumerable Enqueue(T[] bulk) { return bulk.Select(item => Enqueue(item)) .Where(deleted => !deleted.Equals(default(T))).ToList(); } /// /// O(1) Time complexity. /// public T Dequeue() { if (Count == 0) throw new Exception("Empty queue."); var element = queue[start]; start++; //wrap around if (start > queue.Length - 1) { start = 0; if (end == 0) end++; } Count--; if (start == end && Count > 1) end++; //reset if (Count == 0) start = end = 0; return element; } /// /// Time complexity: O(n). /// public IEnumerable Dequeue(int bulkNumber) { var deletedList = new List(); while (bulkNumber > 0 && Count > 0) { var deleted = Dequeue(); if (!deleted.Equals(default(T))) deletedList.Add(deleted); bulkNumber--; } return deletedList; } }