Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vine: use a data to index hash table for priority queue #4051

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions dttools/src/priority_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ See the file COPYING for details.
*/

#include "priority_queue.h"
#include "hash_table.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <float.h>
#include <stdint.h>

#define DEFAULT_CAPACITY 127
#define MAX_PRIORITY DBL_MAX
Expand All @@ -25,6 +27,7 @@ struct priority_queue {
int size;
int capacity;
struct element **elements;
struct hash_table *index_table; // Hash table for data to index mapping

/* The following three cursors are used to iterate over the elements in the numerical order they are stored in the array, which is
different from the order of priorities. Each of them has different concerns when traverse the queue Though the tipical priority-based
Expand All @@ -41,6 +44,10 @@ static 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;

// Update indices in hash table
hash_table_insert(pq->index_table, (char *)pq->elements[i]->data, (void *)(intptr_t)i);
hash_table_insert(pq->index_table, (char *)pq->elements[j]->data, (void *)(intptr_t)j);
}

static int swim(struct priority_queue *pq, int k)
Expand Down Expand Up @@ -127,6 +134,13 @@ struct priority_queue *priority_queue_create(double init_capacity)
pq->base_cursor = 0;
pq->rotate_cursor = 0;

pq->index_table = hash_table_create(0, NULL);
if (!pq->index_table) {
free(pq->elements);
free(pq);
return NULL;
}

return pq;
}

Expand All @@ -150,19 +164,24 @@ int priority_queue_push(struct priority_queue *pq, void *data, double priority)
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;
pq->elements[pq->size] = e;

int new_idx = swim(pq, pq->size - 1);
// Insert data pointer and index into hash table
if (!hash_table_insert(pq->index_table, (char *)data, (void *)(intptr_t)pq->size)) {
free(e);
return 0;
}

int new_idx = swim(pq, pq->size++);
if (new_idx <= pq->rotate_cursor) {
// reset the rotate cursor if the new element is inserted before/equal to it
priority_queue_rotate_reset(pq);
}

Expand Down Expand Up @@ -247,16 +266,15 @@ int priority_queue_update_priority(struct priority_queue *pq, void *data, double
int priority_queue_find_idx(struct priority_queue *pq, void *data)
{
if (!pq) {
return 0;
return -1;
}

for (int i = 0; i < pq->size; i++) {
if (pq->elements[i]->data == data) {
return i;
}
void *idx_ptr = hash_table_lookup(pq->index_table, (char *)data);
if (!idx_ptr) {
return -1;
}

return 0;
return (int)(intptr_t)idx_ptr;
}

int priority_queue_static_next(struct priority_queue *pq)
Expand Down Expand Up @@ -371,5 +389,6 @@ void priority_queue_delete(struct priority_queue *pq)
free(pq->elements[i]);
}
free(pq->elements);
hash_table_delete(pq->index_table);
free(pq);
}
Loading