branch: externals/phpinspect
commit 2d2f9912c1f90a903a3030574c744ead9e6c8398
Author: Hugo Thunnissen <de...@hugot.nl>
Commit: Hugo Thunnissen <de...@hugot.nl>

    Wrap queue items in a queue object
---
 phpinspect-queue.el | 122 ++++++++++++++++++++++++++--------------------------
 test/test-worker.el |   3 +-
 2 files changed, 63 insertions(+), 62 deletions(-)

diff --git a/phpinspect-queue.el b/phpinspect-queue.el
index f772939356..89d851b9c7 100644
--- a/phpinspect-queue.el
+++ b/phpinspect-queue.el
@@ -1,4 +1,20 @@
 
+(cl-defstruct (phpinspect-queue
+               (:constructor phpinspect-make-queue-generated))
+  (-first nil
+         :type phpinspect-queue-item
+         :documentation
+         "The first item in the queue")
+  (-last nil
+        :type phpinspect-queue-item
+        :documentation
+        "The last item in the queue")
+  (subscription  nil
+                 :type function
+                 :read-only t
+                :documentation
+                "A function that should be called when items are
+                enqueued."))
 
 (cl-defstruct (phpinspect-queue-item
                (:constructor phpinspect-make-queue-item))
@@ -6,72 +22,56 @@
         :type phpinspect-queue-item
         :documentation
         "The next item in the queue")
-  (thing nil
+  (value nil
          :type any
          :documentation
-         "The thing stored in the queue")
+         "The value stored in the queue")
   (previous nil
             :type phpinspect-queue-item
             :documentation
-            "The previous item in the queue")
-  (subscription nil
-                :type function
-                :read-only t
-                :documentation
-                "A function that should be called when items are
-                enqueued."))
+            "The previous item in the queue"))
 
-(defsubst phpinspect-make-queue (&optional subscription)
-  (phpinspect-make-queue-item :subscription subscription))
+(define-inline phpinspect-make-queue (&optional subscription)
+  (inline-quote
+   (progn
+     (phpinspect-make-queue-generated :subscription ,subscription))))
 
-;; Recursion causes max-eval-depth error here for long queues. Hence the loop
-;; implementation for these two functions.
-(cl-defmethod phpinspect-queue-last ((item phpinspect-queue-item))
-  "Get the last item in the queue that ITEM is part of."
-  (while (phpinspect-queue-item-next item)
-    (setq item (phpinspect-queue-item-next item)))
-  item)
+(cl-defmethod phpinspect-queue-first ((queue phpinspect-queue))
+  (phpinspect-queue--first queue))
 
-(cl-defmethod phpinspect-queue-first ((item phpinspect-queue-item))
-  "Get the first item in the queue that ITEM is part of."
-  (while (phpinspect-queue-item-previous item)
-      (setq item (phpinspect-queue-item-previous item)))
-  item)
+(cl-defmethod phpinspect-queue-last ((queue phpinspect-queue))
+  (or (phpinspect-queue--last queue) (phpinspect-queue--first queue)))
 
-(cl-defmethod phpinspect-queue-enqueue ((item phpinspect-queue-item) thing)
-  "Add THING to the end of the queue that ITEM is part of."
-  (let ((last (phpinspect-queue-last item)))
-    (if (not (phpinspect-queue-item-thing last))
-        (setf (phpinspect-queue-item-thing last) thing)
-      (setf (phpinspect-queue-item-next last)
-            (phpinspect-make-queue-item
-             :previous last
-             :thing thing
-             :subscription (phpinspect-queue-item-subscription item)))))
-  (when (phpinspect-queue-item-subscription item)
-    (funcall (phpinspect-queue-item-subscription item))))
+(cl-defmethod phpinspect-queue-enqueue ((queue phpinspect-queue) value)
+  "Add VALUE to the end of the queue that ITEM is part of."
+  (let ((last (phpinspect-queue-last queue))
+        (new-item (phpinspect-make-queue-item :value value)))
+    (if (not last)
+        (setf (phpinspect-queue--first queue) new-item)
+      (setf (phpinspect-queue-item-next last) new-item)
+      (setf (phpinspect-queue-item-previous new-item) last))
+    (setf (phpinspect-queue--last queue) new-item))
+  (when (phpinspect-queue-subscription queue)
+    (funcall (phpinspect-queue-subscription queue))))
 
-(cl-defmethod phpinspect-queue-dequeue ((item phpinspect-queue-item))
-  "Remove the thing at the front of the queue that ITEM is part of and return 
it."
-  (let* ((first (phpinspect-queue-first item))
-         (thing (phpinspect-queue-item-thing first))
-         (next (phpinspect-queue-item-next first)))
-    (when next (setf (phpinspect-queue-item-previous next) nil))
-    (cond ((and (eq item first) (not next))
-           (setf (phpinspect-queue-item-thing item)
-                 nil))
-          ((eq item first)
-           (setf (phpinspect-queue-item-thing item)
-                 (phpinspect-queue-item-thing next))
-           (setf (phpinspect-queue-item-next item)
-                 (phpinspect-queue-item-next next))))
-    thing))
+(cl-defmethod phpinspect-queue-dequeue ((queue phpinspect-queue))
+  "Remove the value at the front of the queue that ITEM is part of and return 
it."
+  (let* ((first (phpinspect-queue-first queue))
+         next value)
+    (when first
+      (setq next (phpinspect-queue-item-next first))
+      (setq value (phpinspect-queue-item-value first)))
+    (if next
+        (setf (phpinspect-queue-item-previous next) nil)
+      (setf (phpinspect-queue--last queue) nil))
+    (setf (phpinspect-queue--first queue) next)
+    value))
 
 (defmacro phpinspect-doqueue (place-and-queue &rest body)
   "Loop over queue defined in PLACE-AND-QUEUE executing BODY.
 
 PLACE-AND-QUEUE is a two-member list. The first item should be
-the place that the current thing in the queue should be assigned
+the place that the current value in the queue should be assigned
 to upon each iteration. The second item should be a queue-item
 belonging to the queue that must be iterated over.
 
@@ -81,25 +81,25 @@ BODY can be any form."
         (place (car place-and-queue))
         (queue (cadr place-and-queue)))
     `(let* ((,item-sym (phpinspect-queue-first ,queue))
-            (,place (phpinspect-queue-item-thing ,item-sym)))
+            (,place (when ,item-sym (phpinspect-queue-item-value ,item-sym))))
        (when ,place
          ,@body
          (while (setq ,item-sym (phpinspect-queue-item-next ,item-sym))
-           (setq ,place (phpinspect-queue-item-thing ,item-sym))
+           (setq ,place (phpinspect-queue-item-value ,item-sym))
            ,@body)))))
 
 (cl-defmethod phpinspect-queue-find
-  ((item phpinspect-queue-item) thing comparison-func)
-  "Find THING in the queue that ITEM is part of using COMPARISON-FUNC."
+  ((queue phpinspect-queue) value comparison-func)
+  "Find VALUE in the queue that ITEM is part of using COMPARISON-FUNC."
   (catch 'found
-    (phpinspect-doqueue (current-thing item)
-      (when (funcall comparison-func current-thing thing)
-        (throw 'found current-thing)))))
+    (phpinspect-doqueue (current-value queue)
+      (when (funcall comparison-func current-value value)
+        (throw 'found current-value)))))
 
 (cl-defmethod phpinspect-queue-enqueue-noduplicate
-  ((item phpinspect-queue-item) thing comparison-func)
+  ((queue phpinspect-queue) value comparison-func)
 
-  (when (not (phpinspect-queue-find item thing comparison-func))
-    (phpinspect-queue-enqueue item thing)))
+  (when (not (phpinspect-queue-find queue value comparison-func))
+    (phpinspect-queue-enqueue queue value)))
 
 (provide 'phpinspect-queue)
diff --git a/test/test-worker.el b/test/test-worker.el
index 4d28822009..88916a33c7 100644
--- a/test/test-worker.el
+++ b/test/test-worker.el
@@ -35,7 +35,8 @@
 
     (should (string= "one" (phpinspect-queue-dequeue queue)))
     (should (string= "two" (phpinspect-queue-dequeue queue)))
-    (should (string= "three" (phpinspect-queue-dequeue queue)))))
+    (should (string= "three" (phpinspect-queue-dequeue queue)))
+    (should-not (phpinspect-queue-dequeue queue))))
 
 (ert-deftest phpinspect-queue-subscribe ()
   (let ((be-called nil))

Reply via email to