|
@@ -1,11 +1,13 @@
|
|
|
namespace Invercargill.DataStructures {
|
|
|
|
|
|
- public class Fifo<T> : Enumerable<T> {
|
|
|
+ public class Fifo<T> : Enumerable<T>, Queue<T> {
|
|
|
|
|
|
- public bool is_blocking { get; private set; default = true;}
|
|
|
-
|
|
|
- private FifoItem<T>? first_item = null;
|
|
|
- private FifoItem<T>? last_item = null;
|
|
|
+
|
|
|
+ public bool is_unblocked { get { return !is_blocking; } }
|
|
|
+
|
|
|
+ private bool is_blocking = true;
|
|
|
+ private FifoItem<T>* first_item = null;
|
|
|
+ private FifoItem<T>* last_item = null;
|
|
|
|
|
|
public override int? peek_count() {
|
|
|
return null;
|
|
@@ -24,7 +26,7 @@ namespace Invercargill.DataStructures {
|
|
|
|
|
|
public void push(owned T item) {
|
|
|
mutex.lock();
|
|
|
- var fifo_item = new FifoItem<T>() {
|
|
|
+ FifoItem<T>* fifo_item = new FifoItem<T>() {
|
|
|
item = item,
|
|
|
};
|
|
|
|
|
@@ -33,7 +35,7 @@ namespace Invercargill.DataStructures {
|
|
|
last_item = fifo_item;
|
|
|
}
|
|
|
else {
|
|
|
- last_item.next_item = fifo_item;
|
|
|
+ last_item->next_item = fifo_item;
|
|
|
last_item = fifo_item;
|
|
|
}
|
|
|
|
|
@@ -54,7 +56,7 @@ namespace Invercargill.DataStructures {
|
|
|
last_item = fifo_item;
|
|
|
}
|
|
|
else {
|
|
|
- last_item.next_item = fifo_item;
|
|
|
+ last_item->next_item = fifo_item;
|
|
|
last_item = fifo_item;
|
|
|
}
|
|
|
}
|
|
@@ -63,9 +65,36 @@ namespace Invercargill.DataStructures {
|
|
|
mutex.unlock();
|
|
|
}
|
|
|
|
|
|
+ public T pop() throws SequenceError {
|
|
|
+ mutex.lock();
|
|
|
+ while(is_blocking && first_item == null){
|
|
|
+ cond.wait(mutex);
|
|
|
+ }
|
|
|
+
|
|
|
+ var item = first_item;
|
|
|
+ if(item != null) {
|
|
|
+ first_item = item->next_item;
|
|
|
+ }
|
|
|
+ mutex.unlock();
|
|
|
+ if(item == null) {
|
|
|
+ throw new SequenceError.NO_ELEMENTS("No elements in unblocked queue to pop");
|
|
|
+ }
|
|
|
+ var result = item->item;
|
|
|
+ delete item;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T peek() throws SequenceError {
|
|
|
+ var item = first_item;
|
|
|
+ if(item == null) {
|
|
|
+ throw new SequenceError.NO_ELEMENTS("No elements in queue");
|
|
|
+ }
|
|
|
+ return item->item;
|
|
|
+ }
|
|
|
+
|
|
|
public void push_start(owned T item) {
|
|
|
mutex.lock();
|
|
|
- var fifo_item = new FifoItem<T>() {
|
|
|
+ FifoItem<T>* fifo_item = new FifoItem<T>() {
|
|
|
next_item = first_item,
|
|
|
item = item,
|
|
|
};
|
|
@@ -93,9 +122,11 @@ namespace Invercargill.DataStructures {
|
|
|
private T get_next() {
|
|
|
mutex.lock();
|
|
|
var item = first_item;
|
|
|
- first_item = item.next_item;
|
|
|
+ first_item = item->next_item;
|
|
|
mutex.unlock();
|
|
|
- return item.item;
|
|
|
+ var result = item->item;
|
|
|
+ delete item;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
private Cond cond = Cond ();
|
|
@@ -112,14 +143,15 @@ namespace Invercargill.DataStructures {
|
|
|
var n = first_item;
|
|
|
while(n != null) {
|
|
|
var c = n;
|
|
|
- n = n.next_item;
|
|
|
- c.next_item = null;
|
|
|
+ n = n->next_item;
|
|
|
+ delete c;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ [Compact]
|
|
|
private class FifoItem<T> {
|
|
|
public T item;
|
|
|
- public FifoItem<T>? next_item;
|
|
|
+ public FifoItem<T>* next_item;
|
|
|
}
|
|
|
|
|
|
}
|