/// <summary> /// Adds an object to the priority queue at specified priority level /// </summary> /// <param name="item">The item to add to the queue</param> /// <param name="priority">Priority marker</param> public void Enqueue(TElem item, TPriority priority) { TurboContract.Ensures(this.Count == TurboContract.OldValue(this.Count) + 1); int map = MapPriority(priority); _innerQueue[map].Enqueue(item); _count++; }
/// <summary> /// Sets the capacity to the actual number of elements in the list, if that number is less than 90 percent of current capacity /// </summary> public void TrimExcess() { TurboContract.Ensures(this.Count == TurboContract.OldValue(this.Count)); int minSize = (int)((double)_elemArray.Length * ShrinkRate); if (_size < minSize) { this.SetCapacity(0, _size); } }
/// <summary> /// Adds an element to the end of the list /// </summary> /// <param name="item">Element to add</param> public void AddLast(T item) { TurboContract.Ensures(this.Count == TurboContract.OldValue(this.Count) + 1); if (_size == _elemArray.Length) { this.EnsureCapacity(0, this.Count + 1); } _elemArray[_tail] = item; _tail = (_tail + 1) % _elemArray.Length; _size++; _version++; }
/// <summary> /// Adds an element to the begining of the list /// </summary> /// <param name="item">Element to add</param> public void AddFirst(T item) { TurboContract.Ensures(this.Count == TurboContract.OldValue(this.Count) + 1); if (_size == _elemArray.Length) { this.EnsureCapacity(1, this.Count + 1); } var newHead = (_head - 1 + _elemArray.Length) % _elemArray.Length; _elemArray[newHead] = item; _head = newHead; _size++; _version++; }
/// <summary> /// Removes an element at the begining of the circular list /// </summary> /// <returns>The element at the beginning of the list</returns> public T RemoveFirst() { TurboContract.Requires(this.Count > 0, conditionString: "this.Count > 0"); TurboContract.Ensures(this.Count == TurboContract.OldValue(this.Count) - 1); if (this._size == 0) { throw new InvalidOperationException("Collection is empty"); } T result = _elemArray[this._head]; _elemArray[this._head] = default(T); _head = (_head + 1) % _elemArray.Length; _size--; _version++; return(result); }
/// <summary> /// Removes an element at the ending of the circular list /// </summary> /// <returns>The element at the ending of the list</returns> public T RemoveLast() { TurboContract.Requires(this.Count > 0, conditionString: "this.Count > 0"); TurboContract.Ensures(this.Count == TurboContract.OldValue(this.Count) - 1); if (this._size == 0) { throw new InvalidOperationException("Collection is empty"); } var lastElem = (_tail - 1 + _elemArray.Length) % _elemArray.Length; T result = _elemArray[lastElem]; _elemArray[lastElem] = default(T); _tail = lastElem; _size--; _version++; return(result); }
/// <summary> /// Removes and returns the item at the head of the priority queue (item with the highest available priority) /// </summary> /// <returns>The item that is removed from the head of the queue</returns> public TElem Dequeue() { TurboContract.Requires(this.Count > 0, conditionString: "this.Count > 0"); TurboContract.Ensures(this.Count == TurboContract.OldValue(this.Count) - 1); if (Count == 0) { throw new InvalidOperationException("Collection is empty"); } for (int i = 0; i < _innerQueue.Length; i++) { if (_innerQueue[i].Count > 0) { var res = _innerQueue[i].Dequeue(); _count--; return(res); } } throw new InvalidOperationException("Collection is empty"); }
/// <summary> /// Removes the item at the specified index /// </summary> /// <param name="index">Index of item to remove</param> public void RemoveAt(int index) { TurboContract.Ensures(this.Count == TurboContract.OldValue(this.Count) - 1); if (index < 0 || index >= _size) { throw new ArgumentOutOfRangeException(nameof(index)); } bool moveFromBeginning = index < this.Count / 2; int removePos = (index + _head) % _elemArray.Length; if (moveFromBeginning) { int newHead = (_head + 1) % _elemArray.Length; if (index > 0) { if (_head + index < _elemArray.Length) { Array.Copy(_elemArray, _head, _elemArray, _head + 1, index); } else { if (removePos != 0) { Array.Copy(_elemArray, 0, _elemArray, 1, removePos); } _elemArray[0] = _elemArray[_elemArray.Length - 1]; Array.Copy(_elemArray, _head, _elemArray, _head + 1, _elemArray.Length - _head - 1); } } _elemArray[_head] = default(T); _head = newHead; } else { int newTail = (_tail - 1 + _elemArray.Length) % _elemArray.Length; if (index < _size - 1) { if (removePos <= _tail) { Array.Copy(_elemArray, removePos + 1, _elemArray, removePos, _tail - removePos); } else { if (removePos != _elemArray.Length - 1) { Array.Copy(_elemArray, removePos + 1, _elemArray, removePos, _elemArray.Length - removePos - 1); } _elemArray[_elemArray.Length - 1] = _elemArray[0]; Array.Copy(_elemArray, 1, _elemArray, 0, _tail); } } _elemArray[newTail] = default(T); _tail = newTail; } _size--; _version++; }
/// <summary> /// Inserts an item to the list at the specified index /// </summary> /// <param name="index">Index</param> /// <param name="item">New element</param> public void Insert(int index, T item) { TurboContract.Ensures(this.Count == TurboContract.OldValue(this.Count) + 1); if (index < 0 || index > _size) { throw new ArgumentOutOfRangeException(nameof(index)); } bool moveToBeginning = index <= this.Count / 2; if (_size == _elemArray.Length) { this.EnsureCapacity(moveToBeginning ? 1 : 0, this.Count + 1); } if (moveToBeginning) { int insertPos = (index + _head + _elemArray.Length - 1) % _elemArray.Length; int newHead = (_head - 1 + _elemArray.Length) % _elemArray.Length; if (index > 0) { if (_head <= _elemArray.Length - index) { if (_head > 0) { Array.Copy(_elemArray, _head, _elemArray, _head - 1, index); } else { TurboContract.Assert(_head == 0, conditionString: "_head == 0"); _elemArray[_elemArray.Length - 1] = _elemArray[0]; Array.Copy(_elemArray, 1, _elemArray, 0, insertPos); } } else { Array.Copy(_elemArray, _head, _elemArray, _head - 1, _elemArray.Length - _head); _elemArray[_elemArray.Length - 1] = _elemArray[0]; if (insertPos != 0) { Array.Copy(_elemArray, 1, _elemArray, 0, insertPos); } } } _elemArray[insertPos] = item; _head = newHead; } else { int insertPos = (index + _head) % _elemArray.Length; int newTail = (_tail + 1) % _elemArray.Length; if (index < _size) { if (insertPos <= _tail) { Array.Copy(_elemArray, insertPos, _elemArray, insertPos + 1, _tail - insertPos); } else { Array.Copy(_elemArray, 0, _elemArray, 1, _tail); _elemArray[0] = _elemArray[_elemArray.Length - 1]; if (insertPos != _elemArray.Length - 1) { Array.Copy(_elemArray, insertPos, _elemArray, insertPos + 1, _elemArray.Length - insertPos - 1); } } } _elemArray[insertPos] = item; _tail = newTail; } _size++; _version++; }