You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
3.5 KiB
139 lines
3.5 KiB
4 years ago
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||
|
pragma solidity >=0.6.11;
|
||
|
|
||
|
library QueueLib {
|
||
|
struct Queue {
|
||
4 years ago
|
uint128 first;
|
||
|
uint128 last;
|
||
4 years ago
|
mapping(uint256 => bytes32) queue;
|
||
|
}
|
||
|
|
||
|
function init(Queue storage _q) internal {
|
||
|
if (_q.first == 0) {
|
||
|
_q.first = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
4 years ago
|
function enqueue(Queue storage _q, bytes32 _item)
|
||
|
internal
|
||
|
returns (uint128 _last)
|
||
|
{
|
||
|
_last = _q.last + 1;
|
||
|
_q.last = _last;
|
||
|
if (_item != bytes32(0)) {
|
||
|
// saves gas if we're queueing 0
|
||
|
_q.queue[_last] = _item;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function dequeue(Queue storage _q) internal returns (bytes32 _item) {
|
||
|
uint128 _last = _q.last;
|
||
|
uint128 _first = _q.first;
|
||
|
require(_length(_last, _first) != 0, "Empty");
|
||
|
_item = _q.queue[_first];
|
||
|
if (_item != bytes32(0)) {
|
||
|
// saves gas if we're dequeuing 0
|
||
|
delete _q.queue[_first];
|
||
|
}
|
||
|
_q.first = _first + 1;
|
||
|
}
|
||
|
|
||
|
function enqueue(Queue storage _q, bytes32[] memory _items)
|
||
|
internal
|
||
|
returns (uint128 _last)
|
||
|
{
|
||
|
_last = _q.last;
|
||
4 years ago
|
for (uint256 i = 0; i < _items.length; i += 1) {
|
||
|
_last += 1;
|
||
4 years ago
|
bytes32 _item = _items[i];
|
||
|
if (_item != bytes32(0)) {
|
||
|
_q.queue[_last] = _item;
|
||
|
}
|
||
|
}
|
||
|
_q.last = _last;
|
||
|
}
|
||
|
|
||
4 years ago
|
function dequeue(Queue storage _q, uint256 _number)
|
||
|
internal
|
||
|
returns (bytes32[] memory)
|
||
|
{
|
||
4 years ago
|
uint128 _last = _q.last;
|
||
|
uint128 _first = _q.first;
|
||
|
// Cannot underflow unless state is corrupted
|
||
|
require(_length(_last, _first) >= _number, "Insufficient");
|
||
|
|
||
|
bytes32[] memory _items = new bytes32[](_number);
|
||
|
|
||
4 years ago
|
for (uint256 i = 0; i < _number; i++) {
|
||
4 years ago
|
_items[i] = _q.queue[_first];
|
||
|
delete _q.queue[_first];
|
||
|
_first++;
|
||
|
}
|
||
|
_q.first = _first;
|
||
|
return _items;
|
||
|
}
|
||
|
|
||
4 years ago
|
// NB: this is unfortunately expensive
|
||
4 years ago
|
function contains(Queue storage _q, bytes32 _item)
|
||
|
internal
|
||
|
view
|
||
|
returns (bool)
|
||
|
{
|
||
4 years ago
|
for (uint256 i = _q.first; i <= _q.last; i++) {
|
||
4 years ago
|
if (_q.queue[i] == _item) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
4 years ago
|
function lastItem(Queue storage _q) internal view returns (bytes32) {
|
||
|
return _q.queue[_q.last];
|
||
|
}
|
||
|
|
||
4 years ago
|
function peek(Queue storage _q) internal view returns (bytes32 _item) {
|
||
4 years ago
|
require(!isEmpty(_q), "Empty");
|
||
4 years ago
|
_item = _q.queue[_q.first];
|
||
|
}
|
||
|
|
||
4 years ago
|
function isEmpty(Queue storage _q) internal view returns (bool) {
|
||
|
return _q.last < _q.first;
|
||
4 years ago
|
}
|
||
|
|
||
4 years ago
|
function _length(uint128 _last, uint128 _first)
|
||
|
internal
|
||
|
pure
|
||
|
returns (uint256)
|
||
|
{
|
||
4 years ago
|
return uint256(_last + 1 - _first);
|
||
4 years ago
|
}
|
||
|
|
||
|
function length(Queue storage _q) internal view returns (uint256) {
|
||
4 years ago
|
uint128 _last = _q.last;
|
||
|
uint128 _first = _q.first;
|
||
4 years ago
|
// Cannot underflow unless state is corrupted
|
||
4 years ago
|
return _length(_last, _first);
|
||
4 years ago
|
}
|
||
|
}
|
||
|
|
||
|
contract QueueManager {
|
||
|
using QueueLib for QueueLib.Queue;
|
||
|
QueueLib.Queue internal queue;
|
||
|
|
||
|
constructor() {
|
||
|
queue.init();
|
||
|
}
|
||
4 years ago
|
|
||
4 years ago
|
function queueLength() external view returns (uint256) {
|
||
|
return queue.length();
|
||
|
}
|
||
|
|
||
4 years ago
|
function queueContains(bytes32 _item) external view returns (bool) {
|
||
|
return queue.contains(_item);
|
||
|
}
|
||
|
|
||
|
function queueEnd() external view returns (bytes32) {
|
||
|
return queue.lastItem();
|
||
|
}
|
||
4 years ago
|
}
|