Skip to content

Commit

Permalink
[agroal#463] Deque poll/peek last
Browse files Browse the repository at this point in the history
  • Loading branch information
Jubilee101 committed Jan 5, 2025
1 parent bbd721a commit ec225db
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/include/deque.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ pgagroal_deque_add_with_config(struct deque* deque, char* tag, uintptr_t data, s
uintptr_t
pgagroal_deque_poll(struct deque* deque, char** tag);

/**
* Retrieve value and remove the node from deque's tail.
* Note that if the value was copied into node,
* this function will return the original value and tag
* rather than making a copy of it.
* This function is thread safe, but the returned value is not protected
* @param deque The deque
* @param tag [out] Optional, tag will be returned through if not NULL
* @return The value data if deque's not empty, otherwise 0
*/
uintptr_t
pgagroal_deque_poll_last(struct deque* deque, char** tag);

/**
* Retrieve value without removing the node from deque's head.
* Note that if the value was copied into node,
Expand All @@ -141,6 +154,19 @@ pgagroal_deque_poll(struct deque* deque, char** tag);
uintptr_t
pgagroal_deque_peek(struct deque* deque, char** tag);

/**
* Retrieve value without removing the node from deque's tail.
* Note that if the value was copied into node,
* this function will return the original value and tag
* rather than making a copy of it.
* This function is thread safe, but the returned value is not protected
* @param deque The deque
* @param tag [out] Optional, tag will be returned through if not NULL
* @return The value data if deque's not empty, otherwise 0
*/
uintptr_t
pgagroal_deque_peek_last(struct deque* deque, char** tag);

/**
* Get the data for the specified tag
* @param deque The deque
Expand Down
62 changes: 62 additions & 0 deletions src/libpgagroal/deque.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,42 @@ pgagroal_deque_poll(struct deque* deque, char** tag)
return data;
}

uintptr_t
pgagroal_deque_poll_last(struct deque* deque, char** tag)
{
struct deque_node* tail = NULL;
struct value* val = NULL;
uintptr_t data = 0;
if (deque == NULL || pgagroal_deque_size(deque) == 0)
{
return 0;
}
deque_write_lock(deque);
tail = deque->end->prev;
if (tail == deque->start)
{
deque_unlock(deque);
return 0;
}
// remove node
deque->end->prev = tail->prev;
tail->prev->next = deque->end;
deque->size--;

val = tail->data;
if (tag != NULL)
{
*tag = tail->tag;
}
free(tail);

data = pgagroal_value_data(val);
free(val);

deque_unlock(deque);
return data;
}

uintptr_t
pgagroal_deque_peek(struct deque* deque, char** tag)
{
Expand All @@ -202,6 +238,32 @@ pgagroal_deque_peek(struct deque* deque, char** tag)
return pgagroal_value_data(val);
}

uintptr_t
pgagroal_deque_peek_last(struct deque* deque, char** tag)
{
struct deque_node* tail = NULL;
struct value* val = NULL;
if (deque == NULL || pgagroal_deque_size(deque) == 0)
{
return 0;
}
deque_read_lock(deque);
tail = deque->end->prev;
// this should not happen when size is not 0, but just in case
if (tail == deque->start)
{
deque_unlock(deque);
return 0;
}
val = tail->data;
if (tag != NULL)
{
*tag = tail->tag;
}
deque_unlock(deque);
return pgagroal_value_data(val);
}

uintptr_t
pgagroal_deque_get(struct deque* deque, char* tag)
{
Expand Down

0 comments on commit ec225db

Please sign in to comment.