소스 검색

Add queue interface

Billy Barrow 2 주 전
부모
커밋
f726cced86
4개의 변경된 파일91개의 추가작업 그리고 16개의 파일을 삭제
  1. 46 14
      src/lib/DataStructures/Fifo.vala
  2. 42 0
      src/lib/Interfaces/Queue.vala
  3. 1 0
      src/lib/meson.build
  4. 2 2
      src/tests/TestRunner.vala

+ 46 - 14
src/lib/DataStructures/Fifo.vala

@@ -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;
         }
 
     }

+ 42 - 0
src/lib/Interfaces/Queue.vala

@@ -0,0 +1,42 @@
+
+namespace Invercargill {
+
+    [GenericAccessors]
+    public interface Queue<T> : Enumerable<T> {
+
+        public abstract bool is_unblocked { get; }
+
+        public abstract T peek() throws SequenceError;
+        public abstract T pop() throws SequenceError;
+        public abstract void push(owned T item);
+        public abstract void unblock();
+        
+        public virtual bool try_peek(out T item) {
+            try {
+                item = peek();
+                return true;
+            }
+            catch {
+                item = null;
+                return false;
+            }
+        }
+
+        public virtual bool try_pop(out T item) {
+            try {
+                item = pop();
+                return true;
+            }
+            catch {
+                item = null;
+                return false;
+            }
+        }
+
+        public virtual void push_all(Enumerable<T> items) {
+            items.iterate(i => push(i));
+        }
+
+    }
+
+}

+ 1 - 0
src/lib/meson.build

@@ -91,6 +91,7 @@ sources += files('Interfaces/Elements.vala')
 sources += files('Interfaces/AddressableCollection.vala')
 sources += files('Interfaces/AddressableBytes.vala')
 sources += files('Interfaces/BinaryData.vala')
+sources += files('Interfaces/Queue.vala')
 
 sources += files('DataStructures/Series.vala')
 sources += files('DataStructures/Fifo.vala')

+ 2 - 2
src/tests/TestRunner.vala

@@ -32,8 +32,8 @@ public static int main(string[] args) {
     buffer_speed_test();
     set_speed_test();
     dictionary_speed_test();
-    sorted_series_speed_test();
-    //  fifo_speed_test();
+    //  sorted_series_speed_test(); // Disabled until destructor finished!
+    fifo_speed_test();
 
 
     return result;