Loading...
Searching...
No Matches
as_queue.h
Go to the documentation of this file.
1/*
2 * Copyright 2008-2019 Aerospike, Inc.
3 *
4 * Portions may be licensed to Aerospike, Inc. under one or more contributor
5 * license agreements.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8 * use this file except in compliance with the License. You may obtain a copy of
9 * the License at http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17#pragma once
18
19#include <aerospike/as_std.h>
20#include <string.h>
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26/******************************************************************************
27 * TYPES
28 ******************************************************************************/
29
30/**
31 * A fast, non-thread-safe dynamic queue implementation.
32 * as_queue is not part of the generic as_val family.
33 */
34typedef struct as_queue_s {
35 /**
36 * The block of items in the queue.
37 */
38 uint8_t* data;
39
40 /**
41 * The total number of items allocated.
42 */
43 uint32_t capacity;
44
45 /**
46 * Item offset of head.
47 */
48 uint32_t head;
49
50 /**
51 * Item offset of tail.
52 */
53 uint32_t tail;
54
55 /**
56 * The size of a single item.
57 */
58 uint32_t item_size;
59
60 /**
61 * Total items used which includes items in queue and items popped from queue.
62 */
63 uint32_t total;
64
65 /**
66 * Internal queue flags.
67 */
68 uint32_t flags;
69} as_queue;
70
71/******************************************************************************
72 * MACROS
73 ******************************************************************************/
74
75/**
76 * Initialize a stack allocated as_queue, with item storage on the stack.
77 * as_queue_inita() will transfer stack memory to the heap if a resize is
78 * required.
79 */
80#define as_queue_inita(__q, __item_size, __capacity)\
81(__q)->data = alloca((__capacity) * (__item_size));\
82(__q)->capacity = __capacity;\
83(__q)->head = (__q)->tail = 0;\
84(__q)->item_size = __item_size;\
85(__q)->total = 0;\
86(__q)->flags = 0;
87
88/******************************************************************************
89 * FUNCTIONS
90 ******************************************************************************/
91
92/**
93 * Initialize a stack allocated as_queue, with item storage on the heap.
94 */
95AS_EXTERN bool
96as_queue_init(as_queue* queue, uint32_t item_size, uint32_t capacity);
97
98/**
99 * Create a heap allocated as_queue, with item storage on the heap.
100 */
102as_queue_create(uint32_t item_size, uint32_t capacity);
103
104/**
105 * Release queue memory.
106 */
107AS_EXTERN void
109
110/**
111 * Get the number of items currently in the queue.
112 */
113static inline uint32_t
115{
116 return queue->tail - queue->head;
117}
118
119/**
120 * Is queue empty?
121 */
122static inline bool
124{
125 return queue->tail == queue->head;
126}
127
128/**
129 * Push item to the tail of the queue.
130 */
131AS_EXTERN bool
132as_queue_push(as_queue* queue, const void* ptr);
133
134/**
135 * Push item to the tail of the queue only if size < capacity.
136 */
137AS_EXTERN bool
138as_queue_push_limit(as_queue* queue, const void* ptr);
139
140/**
141 * Push item to the head of the queue.
142 */
143AS_EXTERN bool
144as_queue_push_head(as_queue* queue, const void* ptr);
145
146/**
147 * Push item to the head of the queue only if size < capacity.
148 */
149AS_EXTERN bool
150as_queue_push_head_limit(as_queue* queue, const void* ptr);
151
152/**
153 * Get item at virtual index. For internal use only.
154 */
155static inline void*
156as_queue_get(as_queue* queue, uint32_t index)
157{
158 return &queue->data[(index % queue->capacity) * queue->item_size];
159}
160
161/**
162 * Pop item from the head of the queue.
163 */
164static inline bool
165as_queue_pop(as_queue* queue, void* ptr)
166{
167 if (as_queue_empty(queue)) {
168 return false;
169 }
170
171 memcpy(ptr, as_queue_get(queue, queue->head), queue->item_size);
172 queue->head++;
173
174 // This probably keeps the cache fresher because the queue is fully empty.
175 if (queue->head == queue->tail) {
176 queue->head = queue->tail = 0;
177 }
178 return true;
179}
180
181/**
182 * Pop item from the tail of the queue.
183 */
184static inline bool
185as_queue_pop_tail(as_queue* queue, void* ptr)
186{
187 if (as_queue_empty(queue)) {
188 return false;
189 }
190
191 queue->tail--;
192 memcpy(ptr, as_queue_get(queue, queue->tail), queue->item_size);
193
194 if (queue->head == queue->tail) {
195 queue->head = queue->tail = 0;
196 }
197 return true;
198}
199
200/**
201 * Increment total counter if within capacity.
202 */
203static inline bool
205{
206 if (queue->total < queue->capacity) {
207 queue->total++;
208 return true;
209 }
210 return false;
211}
212
213/**
214 * Decrement total counter.
215 */
216static inline void
218{
219 queue->total--;
220}
221
222#ifdef __cplusplus
223} // end extern "C"
224#endif
static bool as_queue_pop(as_queue *queue, void *ptr)
Definition as_queue.h:165
AS_EXTERN bool as_queue_push_limit(as_queue *queue, const void *ptr)
AS_EXTERN bool as_queue_push_head(as_queue *queue, const void *ptr)
AS_EXTERN void as_queue_destroy(as_queue *queue)
static bool as_queue_empty(as_queue *queue)
Definition as_queue.h:123
static void as_queue_decr_total(as_queue *queue)
Definition as_queue.h:217
static bool as_queue_incr_total(as_queue *queue)
Definition as_queue.h:204
static bool as_queue_pop_tail(as_queue *queue, void *ptr)
Definition as_queue.h:185
AS_EXTERN bool as_queue_init(as_queue *queue, uint32_t item_size, uint32_t capacity)
AS_EXTERN bool as_queue_push_head_limit(as_queue *queue, const void *ptr)
static uint32_t as_queue_size(as_queue *queue)
Definition as_queue.h:114
AS_EXTERN bool as_queue_push(as_queue *queue, const void *ptr)
static void * as_queue_get(as_queue *queue, uint32_t index)
Definition as_queue.h:156
AS_EXTERN as_queue * as_queue_create(uint32_t item_size, uint32_t capacity)
#define AS_EXTERN
Definition as_std.h:25
uint32_t capacity
Definition as_queue.h:43
uint32_t item_size
Definition as_queue.h:58
uint32_t flags
Definition as_queue.h:68
uint32_t tail
Definition as_queue.h:53
uint8_t * data
Definition as_queue.h:38
uint32_t head
Definition as_queue.h:48
uint32_t total
Definition as_queue.h:63