Jelajahi Sumber

flow: PacketPassFairQueue: use SAvl instead of BHeap

ambrop7 13 tahun lalu
induk
melakukan
6875747963
3 mengubah file dengan 53 tambahan dan 36 penghapusan
  1. 24 17
      flow/PacketPassFairQueue.c
  2. 22 19
      flow/PacketPassFairQueue.h
  3. 7 0
      flow/PacketPassFairQueue_tree.h

+ 24 - 17
flow/PacketPassFairQueue.c

@@ -36,11 +36,19 @@
 
 #include <flow/PacketPassFairQueue.h>
 
-static int time_comparator (void *user, uint64_t *time1, uint64_t *time2)
+static int compare_flows (PacketPassFairQueueFlow *f1, PacketPassFairQueueFlow *f2)
 {
-    return B_COMPARE(*time1, *time2);
+    int cmp = B_COMPARE(f1->time, f2->time);
+    if (cmp) {
+        return cmp;
+    }
+    
+    return B_COMPARE((uintptr_t)f1, (uintptr_t)f2);
 }
 
+#include "PacketPassFairQueue_tree.h"
+#include <structure/SAvl_impl.h>
+
 static uint64_t get_current_time (PacketPassFairQueue *m)
 {
     if (m->sending_flow) {
@@ -50,9 +58,8 @@ static uint64_t get_current_time (PacketPassFairQueue *m)
     uint64_t time;
     int have = 0;
     
-    BHeapNode *heap_node = BHeap_GetFirst(&m->queued_heap);
-    if (heap_node) {
-        PacketPassFairQueueFlow *first_flow = UPPER_OBJECT(heap_node, PacketPassFairQueueFlow, queued.heap_node);
+    PacketPassFairQueueFlow *first_flow = PacketPassFairQueue_Tree_GetFirst(&m->queued_tree, 0);
+    if (first_flow) {
         ASSERT(first_flow->is_queued)
         
         time = first_flow->time;
@@ -81,11 +88,10 @@ static void increment_sent_flow (PacketPassFairQueueFlow *flow, uint64_t amount)
     if (amount > FAIRQUEUE_MAX_TIME - flow->time) {
         // get time to subtract
         uint64_t subtract;
-        BHeapNode *heap_node = BHeap_GetFirst(&m->queued_heap);
-        if (!heap_node) {
+        PacketPassFairQueueFlow *first_flow = PacketPassFairQueue_Tree_GetFirst(&m->queued_tree, 0);
+        if (!first_flow) {
             subtract = flow->time;
         } else {
-            PacketPassFairQueueFlow *first_flow = UPPER_OBJECT(heap_node, PacketPassFairQueueFlow, queued.heap_node);
             ASSERT(first_flow->is_queued)
             subtract = first_flow->time;
         }
@@ -117,14 +123,14 @@ static void schedule (PacketPassFairQueue *m)
     ASSERT(!m->sending_flow)
     ASSERT(!m->previous_flow)
     ASSERT(!m->freeing)
-    ASSERT(BHeap_GetFirst(&m->queued_heap))
+    ASSERT(!PacketPassFairQueue_Tree_IsEmpty(&m->queued_tree))
     
     // get first queued flow
-    PacketPassFairQueueFlow *qflow = UPPER_OBJECT(BHeap_GetFirst(&m->queued_heap), PacketPassFairQueueFlow, queued.heap_node);
+    PacketPassFairQueueFlow *qflow = PacketPassFairQueue_Tree_GetFirst(&m->queued_tree, 0);
     ASSERT(qflow->is_queued)
     
     // remove flow from queue
-    BHeap_Remove(&m->queued_heap, &qflow->queued.heap_node);
+    PacketPassFairQueue_Tree_Remove(&m->queued_tree, 0, qflow);
     qflow->is_queued = 0;
     
     // schedule send
@@ -142,7 +148,7 @@ static void schedule_job_handler (PacketPassFairQueue *m)
     // remove previous flow
     m->previous_flow = NULL;
     
-    if (BHeap_GetFirst(&m->queued_heap)) {
+    if (!PacketPassFairQueue_Tree_IsEmpty(&m->queued_tree)) {
         schedule(m);
     }
 }
@@ -167,7 +173,8 @@ static void input_handler_send (PacketPassFairQueueFlow *flow, uint8_t *data, in
     // queue flow
     flow->queued.data = data;
     flow->queued.data_len = data_len;
-    BHeap_Insert(&m->queued_heap, &flow->queued.heap_node);
+    int res = PacketPassFairQueue_Tree_Insert(&m->queued_tree, 0, flow, NULL);
+    ASSERT(res)
     flow->is_queued = 1;
     
     if (!m->sending_flow && !BPending_IsSet(&m->schedule_job)) {
@@ -241,8 +248,8 @@ int PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *outpu
     // no previous flow
     m->previous_flow = NULL;
     
-    // init queued heap
-    BHeap_Init(&m->queued_heap, OFFSET_DIFF(PacketPassFairQueueFlow, time, queued.heap_node), (BHeap_comparator)time_comparator, NULL);
+    // init queued tree
+    PacketPassFairQueue_Tree_Init(&m->queued_tree);
     
     // init flows list
     LinkedList2_Init(&m->flows_list);
@@ -264,7 +271,7 @@ fail0:
 void PacketPassFairQueue_Free (PacketPassFairQueue *m)
 {
     ASSERT(LinkedList2_IsEmpty(&m->flows_list))
-    ASSERT(!BHeap_GetFirst(&m->queued_heap))
+    ASSERT(PacketPassFairQueue_Tree_IsEmpty(&m->queued_tree))
     ASSERT(!m->previous_flow)
     ASSERT(!m->sending_flow)
     DebugCounter_Free(&m->d_ctr);
@@ -336,7 +343,7 @@ void PacketPassFairQueueFlow_Free (PacketPassFairQueueFlow *flow)
     
     // remove from queue
     if (flow->is_queued) {
-        BHeap_Remove(&m->queued_heap, &flow->queued.heap_node);
+        PacketPassFairQueue_Tree_Remove(&m->queued_tree, 0, flow);
     }
     
     // remove from flows list

+ 22 - 19
flow/PacketPassFairQueue.h

@@ -38,7 +38,7 @@
 
 #include <misc/debug.h>
 #include <misc/debugcounter.h>
-#include <structure/BHeap.h>
+#include <structure/SAvl.h>
 #include <structure/LinkedList2.h>
 #include <base/DebugObject.h>
 #include <base/BPending.h>
@@ -51,10 +51,29 @@ typedef void (*PacketPassFairQueue_handler_busy) (void *user);
 
 struct PacketPassFairQueueFlow_s;
 
+#include "PacketPassFairQueue_tree.h"
+#include <structure/SAvl_decl.h>
+
+typedef struct PacketPassFairQueueFlow_s {
+    struct PacketPassFairQueue_s *m;
+    PacketPassFairQueue_handler_busy handler_busy;
+    void *user;
+    PacketPassInterface input;
+    uint64_t time;
+    LinkedList2Node list_node;
+    int is_queued;
+    struct {
+        PacketPassFairQueue_TreeNode tree_node;
+        uint8_t *data;
+        int data_len;
+    } queued;
+    DebugObject d_obj;
+} PacketPassFairQueueFlow;
+
 /**
  * Fair queue using {@link PacketPassInterface}.
  */
-typedef struct {
+typedef struct PacketPassFairQueue_s {
     PacketPassInterface *output;
     BPendingGroup *pg;
     int use_cancel;
@@ -62,7 +81,7 @@ typedef struct {
     struct PacketPassFairQueueFlow_s *sending_flow;
     int sending_len;
     struct PacketPassFairQueueFlow_s *previous_flow;
-    BHeap queued_heap;
+    PacketPassFairQueue_Tree queued_tree;
     LinkedList2 flows_list;
     int freeing;
     BPending schedule_job;
@@ -70,22 +89,6 @@ typedef struct {
     DebugCounter d_ctr;
 } PacketPassFairQueue;
 
-typedef struct PacketPassFairQueueFlow_s {
-    PacketPassFairQueue *m;
-    PacketPassFairQueue_handler_busy handler_busy;
-    void *user;
-    PacketPassInterface input;
-    uint64_t time;
-    LinkedList2Node list_node;
-    int is_queued;
-    struct {
-        BHeapNode heap_node;
-        uint8_t *data;
-        int data_len;
-    } queued;
-    DebugObject d_obj;
-} PacketPassFairQueueFlow;
-
 /**
  * Initializes the queue.
  *

+ 7 - 0
flow/PacketPassFairQueue_tree.h

@@ -0,0 +1,7 @@
+#define SAVL_PARAM_NAME PacketPassFairQueue_Tree
+#define SAVL_PARAM_FEATURE_COUNTS 0
+#define SAVL_PARAM_FEATURE_NOKEYS 1
+#define SAVL_PARAM_TYPE_ENTRY struct PacketPassFairQueueFlow_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