From 6b96f7b952d9c3afc89552bc1ef22ded60a039d0 Mon Sep 17 00:00:00 2001 From: JinZhou5042 Date: Mon, 12 Aug 2024 13:52:54 -0400 Subject: [PATCH 01/13] priority queue data structure --- dttools/src/priority_queue.c | 183 +++++++++++++++++++++++++++++++++++ dttools/src/priority_queue.h | 121 +++++++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 dttools/src/priority_queue.c create mode 100644 dttools/src/priority_queue.h diff --git a/dttools/src/priority_queue.c b/dttools/src/priority_queue.c new file mode 100644 index 0000000000..a7256cbe4c --- /dev/null +++ b/dttools/src/priority_queue.c @@ -0,0 +1,183 @@ +/* +Copyright (C) 2024 The University of Notre Dame +This software is distributed under the GNU General Public License. +See the file COPYING for details. +*/ + +#include "priority_queue.h" + +#include +#include +#include +#include + +#define DEFAULT_CAPACITY 127 +#define MAX_PRIORITY DBL_MAX + +struct element { + void *data; + double priority; +}; + +struct priority_queue { + int size; + int capacity; + struct element **elements; +}; + +struct priority_queue *priority_queue_create(double init_capacity) { + struct priority_queue *pq = (struct priority_queue *)malloc(sizeof(struct priority_queue)); + if (!pq) + return NULL; + + if (init_capacity < 1) { + init_capacity = DEFAULT_CAPACITY; + } + + pq->elements = (struct element **)calloc(init_capacity + 1, sizeof(struct element *)); + if (!pq->elements) { + free(pq); + return NULL; + } + + pq->capacity = init_capacity; + pq->size = 0; + + pq->elements[0] = (struct element *)calloc(1, sizeof(struct element)); + if (!pq->elements[0]) { + free(pq->elements); + free(pq); + return NULL; + } + + pq->elements[0]->priority = MAX_PRIORITY; + + return pq; +} + +int priority_queue_size(struct priority_queue *pq) { + if (!pq) return -1; + + return pq->size; +} + +void swap_elements(struct priority_queue *pq, int i, int j) { + struct element *temp = pq->elements[i]; + pq->elements[i] = pq->elements[j]; + pq->elements[j] = temp; +} + +void swim(struct priority_queue *pq, int k) { + if (!pq) return; + + while (k > 1 && pq->elements[k / 2]->priority < pq->elements[k]->priority) { + swap_elements(pq, k, k / 2); + k /= 2; + } +} + +void sink(struct priority_queue *pq, int k) { + if (!pq) return; + + while (2 * k <= pq->size) { + int j = 2 * k; + if (j < pq->size && pq->elements[j]->priority < pq->elements[j + 1]->priority) { + j++; + } + if (pq->elements[k]->priority >= pq->elements[j]->priority) { + break; + } + swap_elements(pq, k, j); + k = j; + } +} + +int priority_queue_double_capacity(struct priority_queue *pq) { + if (!pq) return 0; + + int new_capacity = pq->capacity * 2; + struct element **new_elements = (struct element **)malloc(sizeof(struct element *) * (new_capacity + 1)); + if (!new_elements) { + return 0; + } + + memcpy(new_elements, pq->elements, sizeof(struct element *) * (pq->size + 1)); + + free(pq->elements); + pq->elements = new_elements; + pq->capacity = new_capacity; + + return 1; +} + +int priority_queue_push(struct priority_queue *pq, void *data, int priority) { + if (!pq) return 0; + + if (pq->size >= pq->capacity) { + if (!priority_queue_double_capacity(pq)) { + return 0; + } + } + struct element *e = (struct element *)malloc(sizeof(struct element)); + if (!e) { + return 0; + } + e->data = data; + e->priority = priority; + + pq->elements[++pq->size] = e; + swim(pq, pq->size); + + return 1; +} + +void *priority_queue_pop(struct priority_queue *pq) { + if (!pq || pq->size == 0) return NULL; + + struct element *e = pq->elements[1]; + void *data = e->data; + pq->elements[1] = pq->elements[pq->size]; + pq->elements[pq->size--] = NULL; + sink(pq, 1); + free(e); + + return data; +} + +void *priority_queue_get_head(struct priority_queue *pq) { + if (!pq || pq->size == 0) return NULL; + + return pq->elements[1]->data; +} + +void *priority_queue_get_element(struct priority_queue *pq, int index) { + if (!pq || pq->size < 1 || index < 1 || index > pq->size) return NULL; + + return pq->elements[index]->data; +} + +int priority_queue_remove(struct priority_queue *pq, void *data) { + if (!pq) return 0; + + for (int i = 1; i <= pq->size; i++) { + if (pq->elements[i]->data == data) { + struct element *e = pq->elements[i]; + pq->elements[i] = pq->elements[pq->size]; + pq->elements[pq->size--] = NULL; + sink(pq, i); + free(e); + return 1; + } + } + return 0; +} + +void priority_queue_destroy(struct priority_queue *pq) { + if (!pq) return; + + for (int i = 0; i <= pq->size; i++) { + free(pq->elements[i]); + } + free(pq->elements); + free(pq); +} \ No newline at end of file diff --git a/dttools/src/priority_queue.h b/dttools/src/priority_queue.h new file mode 100644 index 0000000000..f36e7948eb --- /dev/null +++ b/dttools/src/priority_queue.h @@ -0,0 +1,121 @@ +/* +Copyright (C) 2024 The University of Notre Dame +This software is distributed under the GNU General Public License. +See the file COPYING for details. +*/ + +#ifndef PRIORITY_QUEUE_H +#define PRIORITY_QUEUE_H + +/** +@file priority_queue.h +A general purpose priority queue. +This priority queue module is implemented as a complete binary heap that manages elements with associated priorities. +Each element in the priority queue has a priority, and the queue ensures that the element with the highest priority +can be accessed in constant time. + +For example, to create a priority queue and manipulate its elements: +
+struct priority_queue *pq;
+pq = priority_queue_create(10);
+
+int priority = 5;
+void *data = someDataPointer;
+
+priority_queue_push(pq, data, priority);
+data = priority_queue_pop(pq);
+void *headData = priority_queue_get_head(pq);
+
+ +To list all of the items in a priority queue, use a simple loop: +
+for (int i = 1; i <= priority_queue_size(pq); i++) {
+    void *data = priority_queue_get_element(pq, i);
+    printf("Priority queue contains: %p\n", data);
+}
+
+ +Or use the PRIORITY_QUEUE_ITERATE macro: + +
+void *data;
+PRIORITY_QUEUE_ITERATE (pq, data) {
+    printf("Priority queue contains: %p\n", data);
+}
+
+*/ + + +/** Create a new priority queue. +The 0th element is used as a sentinel with the highest priority to simplify boundary checks in heap operations like swim and sink. +Element with a higher priority is at the top of the heap. +@param init_capacity The initial number of elements in the queue. If zero, a default value will be used. +@return A pointer to a new priority queue. +*/ +struct priority_queue *priority_queue_create(int init_capacity); + +/** Count the elements in a priority queue. +@param pq A pointer to a priority queue. +@return The number of elements in the queue. +*/ +int priority_queue_size(struct priority_queue *pq); + +/** Push an element into a priority queue. +function @ref swim is called to maintain the heap property. +@param pq A pointer to a priority queue. +@param data A pointer to store in the queue. +@param priority The specified priority with the given object. +@return One if the push succeeded, failure otherwise +*/ +int priority_queue_push(struct priority_queue *pq, void *data, double priority); + +/** Pop the element with the highest priority from a priority queue. +function @ref sink is called to maintain the heap property. +@param pq A pointer to a priority queue. +@return The pointer to the top of the heap if any, failure otherwise +*/ +void *priority_queue_pop(struct priority_queue *pq); + +/** Get the element with the highest priority from a priority queue. +Similar to @ref priority_queue_pop, but the element is not removed. +@param pq A pointer to a priority queue. +@return The pointer to the top of the heap if any, failure otherwise +*/ +void *priority_queue_get_head(struct priority_queue *pq); + +/** Get the element with the specified index from a priority queue. +@param pq A pointer to a priority queue. +@param index The index of the element to get. +@return The pointer to the element if any, failure otherwise +*/ +void *priority_queue_get_element(struct priority_queue *pq, int index); + +/** Remove the element with the specified index from a priority queue. +function @ref sink is called to maintain the heap property. +@param pq A pointer to a priority queue. +@param index The index of the element to remove. +@return One if the remove succeeded, failure otherwise +*/ +int priority_queue_remove(struct priority_queue *pq, void *data); + +/** Destroy a priority queue. +@param pq A pointer to a priority queue. +*/ +void priority_queue_destroy(struct priority_queue *pq); + +/** Utility macro to simplify common case of iterating over a priority queue. +Use as follows: + +
+char *data;
+
+PRIORITY_QUEUE_ITERATE(pq, data) {
+	printf("data: %s\n", data);
+}
+
+
+*/ +#define PRIORITY_QUEUE_ITERATE( pq, data ) int i = 1; while ((data = priority_queue_get_element(pq, i++))) + + +#endif From 0712fa336a5f398a3fdbd8afb2f8c37464fdde7e Mon Sep 17 00:00:00 2001 From: JinZhou5042 Date: Mon, 12 Aug 2024 15:43:33 -0400 Subject: [PATCH 02/13] comment fix --- dttools/src/priority_queue.c | 3 +++ dttools/src/priority_queue.h | 37 +++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/dttools/src/priority_queue.c b/dttools/src/priority_queue.c index a7256cbe4c..589856dc5b 100644 --- a/dttools/src/priority_queue.c +++ b/dttools/src/priority_queue.c @@ -43,6 +43,9 @@ struct priority_queue *priority_queue_create(double init_capacity) { pq->capacity = init_capacity; pq->size = 0; + /* The 0th element is used as a sentinel with the highest priority, + which is in order to simplify boundary checks in heap operations like swim and sink. + */ pq->elements[0] = (struct element *)calloc(1, sizeof(struct element)); if (!pq->elements[0]) { free(pq->elements); diff --git a/dttools/src/priority_queue.h b/dttools/src/priority_queue.h index f36e7948eb..dccaa28a2a 100644 --- a/dttools/src/priority_queue.h +++ b/dttools/src/priority_queue.h @@ -10,11 +10,41 @@ See the file COPYING for details. /** @file priority_queue.h A general purpose priority queue. + This priority queue module is implemented as a complete binary heap that manages elements with associated priorities. Each element in the priority queue has a priority, and the queue ensures that the element with the highest priority can be accessed in constant time. -For example, to create a priority queue and manipulate its elements: +If all elements have the same priority, the priority queue behaves differently from a standard queue or stack. +For example, a priority has elements with (priority, data) tuples +[(1, "a"), (1, "b"), (1, "c"), (1, "d"), (1, "e")] +When the first time to pop, the last element "e" will take over the top of the heap and the sink operation is applied. The contents are - +[(1, "e"), (1, "b"), (1, "c"), (1, "d")] +Then, the second time to pop, the last element "d" will take over as the top and he contents are - +[(1, "d"), (1, "b"), (1, "c")] +Similarly, the third time to pop - +[(1, "c"), (1, "b")] +The fourth - +[(1, "b")] +As seen, after the first element is popped, the access order is reversed from the input order. + +When the elements have different priorities, the index order is not the same as the priority order. +For example, a priority is created with elements with (priority, data) tuples +(1, "a") (2, "b") (3, "c") (4, "d") (5, "e") +The order of elements are determined by @ref priority_queue_push. +The first time to push, the contents are - +[(1, "a")] +The second time to push, the priority of the root is less than the new element, the swim operation is applied to the new element - +[(2, "b"), (1, "a")] +The third time - +[(3, "c"), (1, "a"), (2, "b")] +The fourth time - +[(4, "d"), (3, "c"), (2, "b"), (1, "a")] +The fifth time - +[(5, "e"), (4, "d"), (2, "b"), (1, "a"), (3, "c")] +As seen, the iteration order of elements is not the same as the priority order. + +An example to create a priority queue and manipulate its elements:
 struct priority_queue *pq;
 pq = priority_queue_create(10);
@@ -47,7 +77,6 @@ PRIORITY_QUEUE_ITERATE (pq, data) {
 
 
 /** Create a new priority queue.
-The 0th element is used as a sentinel with the highest priority to simplify boundary checks in heap operations like swim and sink.
 Element with a higher priority is at the top of the heap.
 @param init_capacity The initial number of elements in the queue. If zero, a default value will be used.
 @return A pointer to a new priority queue.
@@ -61,7 +90,6 @@ struct priority_queue *priority_queue_create(int init_capacity);
 int priority_queue_size(struct priority_queue *pq);
 
 /** Push an element into a priority queue.
-function @ref swim is called to maintain the heap property.
 @param pq A pointer to a priority queue.
 @param data A pointer to store in the queue.
 @param priority The specified priority with the given object.
@@ -70,7 +98,6 @@ function @ref swim is called to maintain the heap property.
 int priority_queue_push(struct priority_queue *pq, void *data, double priority);
 
 /** Pop the element with the highest priority from a priority queue.
-function @ref sink is called to maintain the heap property.
 @param pq A pointer to a priority queue.
 @return The pointer to the top of the heap if any, failure otherwise
 */
@@ -84,6 +111,7 @@ Similar to @ref priority_queue_pop, but the element is not removed.
 void *priority_queue_get_head(struct priority_queue *pq);
 
 /** Get the element with the specified index from a priority queue.
+The first accessible element is at index 1.
 @param pq A pointer to a priority queue.
 @param index The index of the element to get.
 @return The pointer to the element if any, failure otherwise
@@ -91,7 +119,6 @@ void *priority_queue_get_head(struct priority_queue *pq);
 void *priority_queue_get_element(struct priority_queue *pq, int index);
 
 /** Remove the element with the specified index from a priority queue.
-function @ref sink is called to maintain the heap property.
 @param pq A pointer to a priority queue.
 @param index The index of the element to remove.
 @return One if the remove succeeded, failure otherwise

From 3b6343c43a3ceb4faffd7e7e1781d4d851008a6e Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Mon, 12 Aug 2024 16:15:03 -0400
Subject: [PATCH 03/13] comment operation complexity

---
 dttools/src/priority_queue.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/dttools/src/priority_queue.h b/dttools/src/priority_queue.h
index dccaa28a2a..108ef8d0d7 100644
--- a/dttools/src/priority_queue.h
+++ b/dttools/src/priority_queue.h
@@ -15,6 +15,14 @@ This priority queue module is implemented as a complete binary heap that manages
 Each element in the priority queue has a priority, and the queue ensures that the element with the highest priority
 can be accessed in constant time.
 
+Operation complexity:
+- Create: O(n)
+- Push: O(log n)
+- Pop: O(log n)
+- Get head: O(1)
+- Get element: O(1)
+- Remove element: O(log n)
+
 If all elements have the same priority, the priority queue behaves differently from a standard queue or stack.
 For example, a priority has elements with (priority, data) tuples
 [(1, "a"), (1, "b"), (1, "c"), (1, "d"), (1, "e")]

From 25db49517aa7f2b0b4a5512c0a9badc9599aa8f9 Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Mon, 12 Aug 2024 16:33:17 -0400
Subject: [PATCH 04/13] add apis

---
 dttools/src/priority_queue.c | 22 ++++++++++++++++++++--
 dttools/src/priority_queue.h | 14 ++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/dttools/src/priority_queue.c b/dttools/src/priority_queue.c
index 589856dc5b..349ad94748 100644
--- a/dttools/src/priority_queue.c
+++ b/dttools/src/priority_queue.c
@@ -44,8 +44,7 @@ struct priority_queue *priority_queue_create(double init_capacity) {
     pq->size = 0;
 
     /* The 0th element is used as a sentinel with the highest priority,
-        which is in order to simplify boundary checks in heap operations like swim and sink.
-    */
+        which is in order to simplify boundary checks in heap operations like swim and sink. */
     pq->elements[0] = (struct element *)calloc(1, sizeof(struct element));
     if (!pq->elements[0]) {
         free(pq->elements);
@@ -159,6 +158,25 @@ void *priority_queue_get_element(struct priority_queue *pq, int index) {
     return pq->elements[index]->data;
 }
 
+double priority_queue_get_max_priority(struct priority_queue *pq) {
+    if (!pq || pq->size == 0) return NULL;
+
+    return pq->elements[1]->priority;
+}
+
+double priority_queue_get_min_priority(struct priority_queue *pq) {
+    if (!pq || pq->size == 0) return NULL;
+
+    double min_priority = pq->elements[1]->priority;
+
+    for (int i = 2; i <= pq->size; i++) {
+        min_priority = pq->elements[i]->priority < min_priority ? pq->elements[i]->priority : min_priority;
+    }
+
+    return min_priority;
+}
+
+
 int priority_queue_remove(struct priority_queue *pq, void *data) {
     if (!pq) return 0;
 
diff --git a/dttools/src/priority_queue.h b/dttools/src/priority_queue.h
index 108ef8d0d7..77a993c331 100644
--- a/dttools/src/priority_queue.h
+++ b/dttools/src/priority_queue.h
@@ -21,6 +21,8 @@ Operation complexity:
 - Pop: O(log n)
 - Get head: O(1)
 - Get element: O(1)
+- Get max priority: O(1)
+- Get min priority: O(n)
 - Remove element: O(log n)
 
 If all elements have the same priority, the priority queue behaves differently from a standard queue or stack.
@@ -126,6 +128,18 @@ The first accessible element is at index 1.
 */
 void *priority_queue_get_element(struct priority_queue *pq, int index);
 
+/** Get the highest priority of all elements from a priority queue.
+@param pq A pointer to a priority queue.
+@return The highest priority of the queue.
+*/
+double priority_queue_get_max_priority(struct priority_queue *pq);
+
+/** Get the lowest priority of all elements from a priority queue.
+@param pq A pointer to a priority queue.
+@return The lowest priority of the queue.
+*/
+double priority_queue_get_min_priority(struct priority_queue *pq);
+
 /** Remove the element with the specified index from a priority queue.
 @param pq A pointer to a priority queue.
 @param index The index of the element to remove.

From e7c1f8f8f3c675c29b2d0b0f39431b2a1f73ebc9 Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Mon, 12 Aug 2024 16:34:36 -0400
Subject: [PATCH 05/13] lint

---
 dttools/src/priority_queue.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/dttools/src/priority_queue.c b/dttools/src/priority_queue.c
index 349ad94748..e8ef21312c 100644
--- a/dttools/src/priority_queue.c
+++ b/dttools/src/priority_queue.c
@@ -176,7 +176,6 @@ double priority_queue_get_min_priority(struct priority_queue *pq) {
     return min_priority;
 }
 
-
 int priority_queue_remove(struct priority_queue *pq, void *data) {
     if (!pq) return 0;
 

From 8256c28d03657732525750cc2e43fb264b52d17c Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Mon, 12 Aug 2024 16:38:09 -0400
Subject: [PATCH 06/13] priority_queue_update_priority

---
 dttools/src/priority_queue.c | 27 +++++++++++++++++++++++++++
 dttools/src/priority_queue.h |  8 ++++++++
 2 files changed, 35 insertions(+)

diff --git a/dttools/src/priority_queue.c b/dttools/src/priority_queue.c
index e8ef21312c..2a9d3add0c 100644
--- a/dttools/src/priority_queue.c
+++ b/dttools/src/priority_queue.c
@@ -176,6 +176,33 @@ double priority_queue_get_min_priority(struct priority_queue *pq) {
     return min_priority;
 }
 
+int priority_queue_update_priority(struct priority_queue *pq, void *data, double new_priority) {
+    if (!pq) return 0;
+
+    int index = -1;
+    for (int i = 1; i <= pq->size; i++) {
+        if (pq->elements[i]->data == data) {
+            index = i;
+            break;
+        }
+    }
+
+    if (index == -1) {
+        return 0;
+    }
+
+    double old_priority = pq->elements[index]->priority;
+    pq->elements[index]->priority = new_priority;
+
+    if (new_priority > old_priority) {
+        swim(pq, index);
+    } else if (new_priority < old_priority) {
+        sink(pq, index);
+    }
+
+    return 1;
+}
+
 int priority_queue_remove(struct priority_queue *pq, void *data) {
     if (!pq) return 0;
 
diff --git a/dttools/src/priority_queue.h b/dttools/src/priority_queue.h
index 77a993c331..5f62fddd0f 100644
--- a/dttools/src/priority_queue.h
+++ b/dttools/src/priority_queue.h
@@ -140,6 +140,14 @@ double priority_queue_get_max_priority(struct priority_queue *pq);
 */
 double priority_queue_get_min_priority(struct priority_queue *pq);
 
+/** Update the priority of an element in a priority queue.
+@param pq A pointer to a priority queue.
+@param data The pointer to the element to update.
+@param new_priority The new priority of the element.
+@return One if the update succeeded, failure otherwise
+*/
+int priority_queue_update_priority(struct priority_queue *pq, void *data, double new_priority);
+
 /** Remove the element with the specified index from a priority queue.
 @param pq A pointer to a priority queue.
 @param index The index of the element to remove.

From 8bb933398f86e1d6232492e8e6b1e0ebe3929392 Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Mon, 12 Aug 2024 16:39:11 -0400
Subject: [PATCH 07/13] lint fix

---
 dttools/src/priority_queue.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dttools/src/priority_queue.h b/dttools/src/priority_queue.h
index 5f62fddd0f..15741a59c6 100644
--- a/dttools/src/priority_queue.h
+++ b/dttools/src/priority_queue.h
@@ -175,4 +175,4 @@ PRIORITY_QUEUE_ITERATE(pq, data) {
 #define PRIORITY_QUEUE_ITERATE( pq, data ) int i = 1; while ((data = priority_queue_get_element(pq, i++)))
 
 
-#endif
+#endif
\ No newline at end of file

From ca995f6f044e0a7543637eaa4f9ec7579e06a15d Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Mon, 12 Aug 2024 16:39:56 -0400
Subject: [PATCH 08/13] add blank line at the end

---
 dttools/src/priority_queue.c | 2 +-
 dttools/src/priority_queue.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/dttools/src/priority_queue.c b/dttools/src/priority_queue.c
index 2a9d3add0c..21041479de 100644
--- a/dttools/src/priority_queue.c
+++ b/dttools/src/priority_queue.c
@@ -227,4 +227,4 @@ void priority_queue_destroy(struct priority_queue *pq) {
     }
     free(pq->elements);
     free(pq);
-}
\ No newline at end of file
+}
diff --git a/dttools/src/priority_queue.h b/dttools/src/priority_queue.h
index 15741a59c6..5f62fddd0f 100644
--- a/dttools/src/priority_queue.h
+++ b/dttools/src/priority_queue.h
@@ -175,4 +175,4 @@ PRIORITY_QUEUE_ITERATE(pq, data) {
 #define PRIORITY_QUEUE_ITERATE( pq, data ) int i = 1; while ((data = priority_queue_get_element(pq, i++)))
 
 
-#endif
\ No newline at end of file
+#endif

From ab82fe204ee598a616b603fb789a637e2cd62aff Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Thu, 15 Aug 2024 11:02:23 -0400
Subject: [PATCH 09/13] update Makefile

---
 dttools/src/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/dttools/src/Makefile b/dttools/src/Makefile
index cc9a4cf18e..710a100ea3 100644
--- a/dttools/src/Makefile
+++ b/dttools/src/Makefile
@@ -92,6 +92,7 @@ SOURCES = \
 	ppoll_compat.c \
 	preadwrite.c \
 	process.c \
+	priority_queue.c \
 	random.c \
 	rmonitor.c \
 	rmonitor_poll.c \
@@ -161,6 +162,7 @@ HEADERS_PUBLIC = \
 	md5.h \
 	macros.h \
 	path.h \
+	priority_queue.h \
 	rmonitor_poll.h \
 	rmsummary.h \
 	stringtools.h \

From 2f9a4dc356028175c92a4d11ad2d613117a78a9a Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Thu, 15 Aug 2024 11:11:18 -0400
Subject: [PATCH 10/13] type issue

---
 dttools/src/priority_queue.c | 7 ++++---
 dttools/src/priority_queue.h | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/dttools/src/priority_queue.c b/dttools/src/priority_queue.c
index 21041479de..9d1b1e25dc 100644
--- a/dttools/src/priority_queue.c
+++ b/dttools/src/priority_queue.c
@@ -9,10 +9,11 @@ See the file COPYING for details.
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #define DEFAULT_CAPACITY 127
 #define MAX_PRIORITY DBL_MAX
+#define MIN_PRIORITY DBL_MIN
 
 struct element {
     void *data;
@@ -159,13 +160,13 @@ void *priority_queue_get_element(struct priority_queue *pq, int index) {
 }
 
 double priority_queue_get_max_priority(struct priority_queue *pq) {
-    if (!pq || pq->size == 0) return NULL;
+    if (!pq || pq->size == 0) return MIN_PRIORITY;
 
     return pq->elements[1]->priority;
 }
 
 double priority_queue_get_min_priority(struct priority_queue *pq) {
-    if (!pq || pq->size == 0) return NULL;
+    if (!pq || pq->size == 0) return MAX_PRIORITY;
 
     double min_priority = pq->elements[1]->priority;
 
diff --git a/dttools/src/priority_queue.h b/dttools/src/priority_queue.h
index 5f62fddd0f..b50ca3659c 100644
--- a/dttools/src/priority_queue.h
+++ b/dttools/src/priority_queue.h
@@ -91,7 +91,7 @@ Element with a higher priority is at the top of the heap.
 @param init_capacity The initial number of elements in the queue. If zero, a default value will be used.
 @return A pointer to a new priority queue.
 */
-struct priority_queue *priority_queue_create(int init_capacity);
+struct priority_queue *priority_queue_create(double init_capacity);
 
 /** Count the elements in a priority queue.
 @param pq A pointer to a priority queue.

From f4822c0d8f96cdcbc55382073fd4a4a55c4efa12 Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Thu, 15 Aug 2024 11:20:58 -0400
Subject: [PATCH 11/13] double priority

---
 dttools/src/priority_queue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dttools/src/priority_queue.c b/dttools/src/priority_queue.c
index 9d1b1e25dc..b827c0c513 100644
--- a/dttools/src/priority_queue.c
+++ b/dttools/src/priority_queue.c
@@ -113,7 +113,7 @@ int priority_queue_double_capacity(struct priority_queue *pq) {
     return 1;
 }
 
-int priority_queue_push(struct priority_queue *pq, void *data, int priority) {
+int priority_queue_push(struct priority_queue *pq, void *data, double priority) {
     if (!pq) return 0;
 
     if (pq->size >= pq->capacity) {

From 5636acd2b347da4f1c80d5e614999ea844639853 Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Thu, 15 Aug 2024 11:23:57 -0400
Subject: [PATCH 12/13] lint issue

---
 dttools/src/priority_queue.c | 356 +++++++++++++++++++----------------
 1 file changed, 192 insertions(+), 164 deletions(-)

diff --git a/dttools/src/priority_queue.c b/dttools/src/priority_queue.c
index b827c0c513..694bce8657 100644
--- a/dttools/src/priority_queue.c
+++ b/dttools/src/priority_queue.c
@@ -16,216 +16,244 @@ See the file COPYING for details.
 #define MIN_PRIORITY DBL_MIN
 
 struct element {
-    void *data;
-    double priority;
+	void *data;
+	double priority;
 };
 
 struct priority_queue {
-    int size;
-    int capacity;
-    struct element **elements;
+	int size;
+	int capacity;
+	struct element **elements;
 };
 
-struct priority_queue *priority_queue_create(double init_capacity) {
-    struct priority_queue *pq = (struct priority_queue *)malloc(sizeof(struct priority_queue));
-    if (!pq)
-        return NULL;
-
-    if (init_capacity < 1) {
-        init_capacity = DEFAULT_CAPACITY;
-    }
-
-    pq->elements = (struct element **)calloc(init_capacity + 1, sizeof(struct element *));
-    if (!pq->elements) {
-        free(pq);
-        return NULL;
-    }
-
-    pq->capacity = init_capacity;
-    pq->size = 0;
-
-    /* The 0th element is used as a sentinel with the highest priority,
-        which is in order to simplify boundary checks in heap operations like swim and sink. */
-    pq->elements[0] = (struct element *)calloc(1, sizeof(struct element));
-    if (!pq->elements[0]) {
-        free(pq->elements);
-        free(pq);
-        return NULL;
-    }
-
-    pq->elements[0]->priority = MAX_PRIORITY;
-
-    return pq;
+struct priority_queue *priority_queue_create(double init_capacity)
+{
+	struct priority_queue *pq = (struct priority_queue *)malloc(sizeof(struct priority_queue));
+	if (!pq)
+		return NULL;
+
+	if (init_capacity < 1) {
+		init_capacity = DEFAULT_CAPACITY;
+	}
+
+	pq->elements = (struct element **)calloc(init_capacity + 1, sizeof(struct element *));
+	if (!pq->elements) {
+		free(pq);
+		return NULL;
+	}
+
+	pq->capacity = init_capacity;
+	pq->size = 0;
+
+	/* The 0th element is used as a sentinel with the highest priority,
+	    which is in order to simplify boundary checks in heap operations like swim and sink. */
+	pq->elements[0] = (struct element *)calloc(1, sizeof(struct element));
+	if (!pq->elements[0]) {
+		free(pq->elements);
+		free(pq);
+		return NULL;
+	}
+
+	pq->elements[0]->priority = MAX_PRIORITY;
+
+	return pq;
 }
 
-int priority_queue_size(struct priority_queue *pq) {
-    if (!pq) return -1;
+int priority_queue_size(struct priority_queue *pq)
+{
+	if (!pq)
+		return -1;
 
-    return pq->size;
+	return pq->size;
 }
 
-void swap_elements(struct priority_queue *pq, int i, int j) {
-    struct element *temp = pq->elements[i];
-    pq->elements[i] = pq->elements[j];
-    pq->elements[j] = temp;
+void swap_elements(struct priority_queue *pq, int i, int j)
+{
+	struct element *temp = pq->elements[i];
+	pq->elements[i] = pq->elements[j];
+	pq->elements[j] = temp;
 }
 
-void swim(struct priority_queue *pq, int k) {
-    if (!pq) return;
+void swim(struct priority_queue *pq, int k)
+{
+	if (!pq)
+		return;
 
-    while (k > 1 && pq->elements[k / 2]->priority < pq->elements[k]->priority) {
-        swap_elements(pq, k, k / 2);
-        k /= 2;
-    }
+	while (k > 1 && pq->elements[k / 2]->priority < pq->elements[k]->priority) {
+		swap_elements(pq, k, k / 2);
+		k /= 2;
+	}
 }
 
-void sink(struct priority_queue *pq, int k) {
-    if (!pq) return;
-
-    while (2 * k <= pq->size) {
-        int j = 2 * k;
-        if (j < pq->size && pq->elements[j]->priority < pq->elements[j + 1]->priority) {
-            j++;
-        }
-        if (pq->elements[k]->priority >= pq->elements[j]->priority) {
-            break;
-        }
-        swap_elements(pq, k, j);
-        k = j;
-    }
+void sink(struct priority_queue *pq, int k)
+{
+	if (!pq)
+		return;
+
+	while (2 * k <= pq->size) {
+		int j = 2 * k;
+		if (j < pq->size && pq->elements[j]->priority < pq->elements[j + 1]->priority) {
+			j++;
+		}
+		if (pq->elements[k]->priority >= pq->elements[j]->priority) {
+			break;
+		}
+		swap_elements(pq, k, j);
+		k = j;
+	}
 }
 
-int priority_queue_double_capacity(struct priority_queue *pq) {
-    if (!pq) return 0;
+int priority_queue_double_capacity(struct priority_queue *pq)
+{
+	if (!pq)
+		return 0;
 
-    int new_capacity = pq->capacity * 2;
-    struct element **new_elements = (struct element **)malloc(sizeof(struct element *) * (new_capacity + 1));
-    if (!new_elements) {
-        return 0;
-    }
+	int new_capacity = pq->capacity * 2;
+	struct element **new_elements = (struct element **)malloc(sizeof(struct element *) * (new_capacity + 1));
+	if (!new_elements) {
+		return 0;
+	}
 
-    memcpy(new_elements, pq->elements, sizeof(struct element *) * (pq->size + 1));
+	memcpy(new_elements, pq->elements, sizeof(struct element *) * (pq->size + 1));
 
-    free(pq->elements);
-    pq->elements = new_elements;
-    pq->capacity = new_capacity;
+	free(pq->elements);
+	pq->elements = new_elements;
+	pq->capacity = new_capacity;
 
-    return 1;
+	return 1;
 }
 
-int priority_queue_push(struct priority_queue *pq, void *data, double priority) {
-    if (!pq) return 0;
-
-    if (pq->size >= pq->capacity) {
-        if (!priority_queue_double_capacity(pq)) {
-            return 0;
-        }
-    }
-    struct element *e = (struct element *)malloc(sizeof(struct element));
-    if (!e) {
-        return 0;
-    }
-    e->data = data;
-    e->priority = priority;
-
-    pq->elements[++pq->size] = e;
-    swim(pq, pq->size);
-
-    return 1;
+int priority_queue_push(struct priority_queue *pq, void *data, double priority)
+{
+	if (!pq)
+		return 0;
+
+	if (pq->size >= pq->capacity) {
+		if (!priority_queue_double_capacity(pq)) {
+			return 0;
+		}
+	}
+	struct element *e = (struct element *)malloc(sizeof(struct element));
+	if (!e) {
+		return 0;
+	}
+	e->data = data;
+	e->priority = priority;
+
+	pq->elements[++pq->size] = e;
+	swim(pq, pq->size);
+
+	return 1;
 }
 
-void *priority_queue_pop(struct priority_queue *pq) {
-    if (!pq || pq->size == 0) return NULL;
+void *priority_queue_pop(struct priority_queue *pq)
+{
+	if (!pq || pq->size == 0)
+		return NULL;
 
-    struct element *e = pq->elements[1];
-    void *data = e->data;
-    pq->elements[1] = pq->elements[pq->size];
-    pq->elements[pq->size--] = NULL;
-    sink(pq, 1);
-    free(e);
+	struct element *e = pq->elements[1];
+	void *data = e->data;
+	pq->elements[1] = pq->elements[pq->size];
+	pq->elements[pq->size--] = NULL;
+	sink(pq, 1);
+	free(e);
 
-    return data;
+	return data;
 }
 
-void *priority_queue_get_head(struct priority_queue *pq) {
-    if (!pq || pq->size == 0) return NULL;
+void *priority_queue_get_head(struct priority_queue *pq)
+{
+	if (!pq || pq->size == 0)
+		return NULL;
 
-    return pq->elements[1]->data;
+	return pq->elements[1]->data;
 }
 
-void *priority_queue_get_element(struct priority_queue *pq, int index) {
-    if (!pq || pq->size < 1 || index < 1 || index > pq->size) return NULL;
+void *priority_queue_get_element(struct priority_queue *pq, int index)
+{
+	if (!pq || pq->size < 1 || index < 1 || index > pq->size)
+		return NULL;
 
-    return pq->elements[index]->data;
+	return pq->elements[index]->data;
 }
 
-double priority_queue_get_max_priority(struct priority_queue *pq) {
-    if (!pq || pq->size == 0) return MIN_PRIORITY;
+double priority_queue_get_max_priority(struct priority_queue *pq)
+{
+	if (!pq || pq->size == 0)
+		return MIN_PRIORITY;
 
-    return pq->elements[1]->priority;
+	return pq->elements[1]->priority;
 }
 
-double priority_queue_get_min_priority(struct priority_queue *pq) {
-    if (!pq || pq->size == 0) return MAX_PRIORITY;
+double priority_queue_get_min_priority(struct priority_queue *pq)
+{
+	if (!pq || pq->size == 0)
+		return MAX_PRIORITY;
 
-    double min_priority = pq->elements[1]->priority;
+	double min_priority = pq->elements[1]->priority;
 
-    for (int i = 2; i <= pq->size; i++) {
-        min_priority = pq->elements[i]->priority < min_priority ? pq->elements[i]->priority : min_priority;
-    }
+	for (int i = 2; i <= pq->size; i++) {
+		min_priority = pq->elements[i]->priority < min_priority ? pq->elements[i]->priority : min_priority;
+	}
 
-    return min_priority;
+	return min_priority;
 }
 
-int priority_queue_update_priority(struct priority_queue *pq, void *data, double new_priority) {
-    if (!pq) return 0;
-
-    int index = -1;
-    for (int i = 1; i <= pq->size; i++) {
-        if (pq->elements[i]->data == data) {
-            index = i;
-            break;
-        }
-    }
-
-    if (index == -1) {
-        return 0;
-    }
-
-    double old_priority = pq->elements[index]->priority;
-    pq->elements[index]->priority = new_priority;
-
-    if (new_priority > old_priority) {
-        swim(pq, index);
-    } else if (new_priority < old_priority) {
-        sink(pq, index);
-    }
-
-    return 1;
+int priority_queue_update_priority(struct priority_queue *pq, void *data, double new_priority)
+{
+	if (!pq)
+		return 0;
+
+	int index = -1;
+	for (int i = 1; i <= pq->size; i++) {
+		if (pq->elements[i]->data == data) {
+			index = i;
+			break;
+		}
+	}
+
+	if (index == -1) {
+		return 0;
+	}
+
+	double old_priority = pq->elements[index]->priority;
+	pq->elements[index]->priority = new_priority;
+
+	if (new_priority > old_priority) {
+		swim(pq, index);
+	} else if (new_priority < old_priority) {
+		sink(pq, index);
+	}
+
+	return 1;
 }
 
-int priority_queue_remove(struct priority_queue *pq, void *data) {
-    if (!pq) return 0;
-
-    for (int i = 1; i <= pq->size; i++) {
-        if (pq->elements[i]->data == data) {
-            struct element *e = pq->elements[i];
-            pq->elements[i] = pq->elements[pq->size];
-            pq->elements[pq->size--] = NULL;
-            sink(pq, i);
-            free(e);
-            return 1;
-        }
-    }
-    return 0;
+int priority_queue_remove(struct priority_queue *pq, void *data)
+{
+	if (!pq)
+		return 0;
+
+	for (int i = 1; i <= pq->size; i++) {
+		if (pq->elements[i]->data == data) {
+			struct element *e = pq->elements[i];
+			pq->elements[i] = pq->elements[pq->size];
+			pq->elements[pq->size--] = NULL;
+			sink(pq, i);
+			free(e);
+			return 1;
+		}
+	}
+	return 0;
 }
 
-void priority_queue_destroy(struct priority_queue *pq) {
-    if (!pq) return;
+void priority_queue_destroy(struct priority_queue *pq)
+{
+	if (!pq)
+		return;
 
-    for (int i = 0; i <= pq->size; i++) {
-        free(pq->elements[i]);
-    }
-    free(pq->elements);
-    free(pq);
+	for (int i = 0; i <= pq->size; i++) {
+		free(pq->elements[i]);
+	}
+	free(pq->elements);
+	free(pq);
 }

From 6cc0037116699e92271d2e51d5f64e04f18b2bb2 Mon Sep 17 00:00:00 2001
From: JinZhou5042 
Date: Mon, 19 Aug 2024 10:06:16 -0400
Subject: [PATCH 13/13] test

---
 dttools/src/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dttools/src/Makefile b/dttools/src/Makefile
index 710a100ea3..3e15af49df 100644
--- a/dttools/src/Makefile
+++ b/dttools/src/Makefile
@@ -91,8 +91,8 @@ SOURCES = \
 	pattern.c \
 	ppoll_compat.c \
 	preadwrite.c \
-	process.c \
 	priority_queue.c \
+	process.c \
 	random.c \
 	rmonitor.c \
 	rmonitor_poll.c \