Jelajahi Sumber

flow: PacketPassPriorityQueue: use SAvl instead of BHeap

ambrop7 13 tahun lalu
induk
melakukan
83123063ca

+ 20 - 11
flow/PacketPassPriorityQueue.c

@@ -35,23 +35,31 @@
 
 #include <flow/PacketPassPriorityQueue.h>
 
-static int int_comparator (void *user, int *prio1, int *prio2)
+static int compare_flows (PacketPassPriorityQueueFlow *f1, PacketPassPriorityQueueFlow *f2)
 {
-    return B_COMPARE(*prio1, *prio2);
+    int cmp = B_COMPARE(f1->priority, f2->priority);
+    if (cmp) {
+        return cmp;
+    }
+    
+    return B_COMPARE((uintptr_t)f1, (uintptr_t)f2);
 }
 
+#include "PacketPassPriorityQueue_tree.h"
+#include <structure/SAvl_impl.h>
+
 static void schedule (PacketPassPriorityQueue *m)
 {
     ASSERT(!m->sending_flow)
     ASSERT(!m->freeing)
-    ASSERT(BHeap_GetFirst(&m->queued_heap))
+    ASSERT(!PacketPassPriorityQueue__Tree_IsEmpty(&m->queued_tree))
     
     // get first queued flow
-    PacketPassPriorityQueueFlow *qflow = UPPER_OBJECT(BHeap_GetFirst(&m->queued_heap), PacketPassPriorityQueueFlow, queued.heap_node);
+    PacketPassPriorityQueueFlow *qflow = PacketPassPriorityQueue__Tree_GetFirst(&m->queued_tree, 0);
     ASSERT(qflow->is_queued)
     
     // remove flow from queue
-    BHeap_Remove(&m->queued_heap, &qflow->queued.heap_node);
+    PacketPassPriorityQueue__Tree_Remove(&m->queued_tree, 0, qflow);
     qflow->is_queued = 0;
     
     // schedule send
@@ -65,7 +73,7 @@ static void schedule_job_handler (PacketPassPriorityQueue *m)
     ASSERT(!m->freeing)
     DebugObject_Access(&m->d_obj);
     
-    if (BHeap_GetFirst(&m->queued_heap)) {
+    if (!PacketPassPriorityQueue__Tree_IsEmpty(&m->queued_tree)) {
         schedule(m);
     }
 }
@@ -82,7 +90,8 @@ static void input_handler_send (PacketPassPriorityQueueFlow *flow, uint8_t *data
     // queue flow
     flow->queued.data = data;
     flow->queued.data_len = data_len;
-    BHeap_Insert(&m->queued_heap, &flow->queued.heap_node);
+    int res = PacketPassPriorityQueue__Tree_Insert(&m->queued_tree, 0, flow, NULL);
+    ASSERT(res)
     flow->is_queued = 1;
     
     if (!m->sending_flow && !BPending_IsSet(&m->schedule_job)) {
@@ -136,8 +145,8 @@ void PacketPassPriorityQueue_Init (PacketPassPriorityQueue *m, PacketPassInterfa
     // not sending
     m->sending_flow = NULL;
     
-    // init queued heap
-    BHeap_Init(&m->queued_heap, OFFSET_DIFF(PacketPassPriorityQueueFlow, priority, queued.heap_node), (BHeap_comparator)int_comparator, NULL);
+    // init queued tree
+    PacketPassPriorityQueue__Tree_Init(&m->queued_tree);
     
     // not freeing
     m->freeing = 0;
@@ -151,7 +160,7 @@ void PacketPassPriorityQueue_Init (PacketPassPriorityQueue *m, PacketPassInterfa
 
 void PacketPassPriorityQueue_Free (PacketPassPriorityQueue *m)
 {
-    ASSERT(!BHeap_GetFirst(&m->queued_heap))
+    ASSERT(PacketPassPriorityQueue__Tree_IsEmpty(&m->queued_tree))
     ASSERT(!m->sending_flow)
     DebugCounter_Free(&m->d_ctr);
     DebugObject_Free(&m->d_obj);
@@ -212,7 +221,7 @@ void PacketPassPriorityQueueFlow_Free (PacketPassPriorityQueueFlow *flow)
     
     // remove from queue
     if (flow->is_queued) {
-        BHeap_Remove(&m->queued_heap, &flow->queued.heap_node);
+        PacketPassPriorityQueue__Tree_Remove(&m->queued_tree, 0, flow);
     }
     
     // free input

+ 20 - 17
flow/PacketPassPriorityQueue.h

@@ -37,7 +37,7 @@
 #include <stdint.h>
 
 #include <misc/debugcounter.h>
-#include <structure/BHeap.h>
+#include <structure/SAvl.h>
 #include <base/DebugObject.h>
 #include <base/BPending.h>
 #include <flow/PacketPassInterface.h>
@@ -46,36 +46,39 @@ typedef void (*PacketPassPriorityQueue_handler_busy) (void *user);
 
 struct PacketPassPriorityQueueFlow_s;
 
-/**
- * Priority queue using {@link PacketPassInterface}.
- */
-typedef struct {
-    PacketPassInterface *output;
-    BPendingGroup *pg;
-    int use_cancel;
-    struct PacketPassPriorityQueueFlow_s *sending_flow;
-    BHeap queued_heap;
-    int freeing;
-    BPending schedule_job;
-    DebugObject d_obj;
-    DebugCounter d_ctr;
-} PacketPassPriorityQueue;
+#include "PacketPassPriorityQueue_tree.h"
+#include <structure/SAvl_decl.h>
 
 typedef struct PacketPassPriorityQueueFlow_s {
-    PacketPassPriorityQueue *m;
+    struct PacketPassPriorityQueue_s *m;
     int priority;
     PacketPassPriorityQueue_handler_busy handler_busy;
     void *user;
     PacketPassInterface input;
     int is_queued;
     struct {
-        BHeapNode heap_node;
+        PacketPassPriorityQueue__TreeNode tree_node;
         uint8_t *data;
         int data_len;
     } queued;
     DebugObject d_obj;
 } PacketPassPriorityQueueFlow;
 
+/**
+ * Priority queue using {@link PacketPassInterface}.
+ */
+typedef struct PacketPassPriorityQueue_s {
+    PacketPassInterface *output;
+    BPendingGroup *pg;
+    int use_cancel;
+    struct PacketPassPriorityQueueFlow_s *sending_flow;
+    PacketPassPriorityQueue__Tree queued_tree;
+    int freeing;
+    BPending schedule_job;
+    DebugObject d_obj;
+    DebugCounter d_ctr;
+} PacketPassPriorityQueue;
+
 /**
  * Initializes the queue.
  *

+ 7 - 0
flow/PacketPassPriorityQueue_tree.h

@@ -0,0 +1,7 @@
+#define SAVL_PARAM_NAME PacketPassPriorityQueue__Tree
+#define SAVL_PARAM_FEATURE_COUNTS 0
+#define SAVL_PARAM_FEATURE_NOKEYS 1
+#define SAVL_PARAM_TYPE_ENTRY struct PacketPassPriorityQueueFlow_s
+#define SAVL_PARAM_TYPE_ARG int
+#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_flows((entry1), (entry2))
+#define SAVL_PARAM_MEMBER_NODE queued.tree_node