diff options
| author | Paul Buetow <pbuetow@mimecast.com> | 2018-03-06 17:38:59 +0000 |
|---|---|---|
| committer | Paul Buetow <pbuetow@mimecast.com> | 2018-03-06 17:38:59 +0000 |
| commit | 26b3b3e368a79ce29df732ea04e72a4c002ae2ce (patch) | |
| tree | e3fc8d7461ab371279f7bf9c692096cd39cc92f6 /ioreplay/src/datas | |
| parent | ae2221660f9b411fa78cdf8034f0803e9a870cde (diff) | |
rename into ioriot
Diffstat (limited to 'ioreplay/src/datas')
| -rw-r--r-- | ioreplay/src/datas/amap.c | 264 | ||||
| -rw-r--r-- | ioreplay/src/datas/amap.h | 49 | ||||
| -rw-r--r-- | ioreplay/src/datas/btree.c | 169 | ||||
| -rw-r--r-- | ioreplay/src/datas/btree.h | 52 | ||||
| -rw-r--r-- | ioreplay/src/datas/hmap.c | 362 | ||||
| -rw-r--r-- | ioreplay/src/datas/hmap.h | 56 | ||||
| -rw-r--r-- | ioreplay/src/datas/list.c | 279 | ||||
| -rw-r--r-- | ioreplay/src/datas/list.h | 56 | ||||
| -rw-r--r-- | ioreplay/src/datas/rbuffer.c | 147 | ||||
| -rw-r--r-- | ioreplay/src/datas/rbuffer.h | 102 | ||||
| -rw-r--r-- | ioreplay/src/datas/stack.c | 85 | ||||
| -rw-r--r-- | ioreplay/src/datas/stack.h | 43 |
12 files changed, 0 insertions, 1664 deletions
diff --git a/ioreplay/src/datas/amap.c b/ioreplay/src/datas/amap.c deleted file mode 100644 index 806a3f8..0000000 --- a/ioreplay/src/datas/amap.c +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "amap.h" - -/** - * @brief Creates a new array map - * - * @param size The array map size - * @param mmapped true if the memory should be mmapped - * @return The new amap object - */ -static amap_s *_amap_new(long size, bool mmapped) -{ - amap_s *a = NULL; - void ***arrays = NULL; - - // Calculate a multiple of 1024, but at least in size of 'size'. - if (size % 1024 != 0) { - size = 1024*(1+(long)(size/1024)); - } - - if (size < 1) { - Error("Size overflow"); - } - - int num_arrays = size / AMAP_MAX_ARRAY_LENGTH; - - if (mmapped) { - a = Mmapshared(amap_s); - arrays = Cmapshared(num_arrays, void**); - } else { - a = Malloc(amap_s); - arrays = Calloc(num_arrays, void**); - } - - for (int i = 0; i < num_arrays; ++i) { - if (mmapped) { - //Put("%d", AMAP_MAX_ARRAY_LENGTH); - arrays[i] = Cmapshared(AMAP_MAX_ARRAY_LENGTH, void*); - } else { - arrays[i] = Calloc(AMAP_MAX_ARRAY_LENGTH, void*); - } - for (int j = 0; j < AMAP_MAX_ARRAY_LENGTH; ++j) { - arrays[i][j] = NULL; - } - } - - a->arrays = arrays; - a->num_arrays = num_arrays; - a->size = size; - a->data_destroy = NULL; - a->mmapped = mmapped; - - return a; -} - -/** - * @brief Creates a new array map - * - * @param size The array map size - * @return The new amap object - */ -amap_s* amap_new(const long size) -{ - return _amap_new(size, false); -} - -/** - * @brief Creates a new mmapped array map - * - * @param size The array map size - * @return The new amap object - */ -amap_s* amap_new_mmapped(const long size) -{ - return _amap_new(size, true); -} - -/** - * @brief Destroys a mmap object - * - * @a The new amap object - */ -void amap_destroy(amap_s* a) -{ - if (!a) { - return; - } - - // Don't bother, the mmapped version of amap will stay alive until - // process terminations. And after process termination everything - // will be cleaned up automatically by Linux. - if (a->mmapped) { - return; - } - - for (int i = 0; i < a->num_arrays; ++i) { - if (a->data_destroy) { - for (int j = 0; j < AMAP_MAX_ARRAY_LENGTH; ++j) - if (a->arrays[i][j]) { - a->data_destroy(a->arrays[i][j]); - } - } - free(a->arrays[i]); - } - free(a->arrays); - free(a); -} - -/** - * @brief Resets a mmap object - * - * This resets all entries to NULL. - * - * @a The new amap object - */ -void amap_reset(amap_s* a) -{ - for (int i = 0; i < a->num_arrays; ++i) { - for (int j = 0; j < AMAP_MAX_ARRAY_LENGTH; ++j) { - if (a->data_destroy) { - if (a->arrays[i][j]) { - a->data_destroy(a->arrays[i][j]); - } - } - a->arrays[i][j] = NULL; - } - } -} - -int amap_set(amap_s *a, const long position, void* value) -{ - if (position >= a->size) - return -1; - int which_array = position / AMAP_MAX_ARRAY_LENGTH; - int array_pos = position % AMAP_MAX_ARRAY_LENGTH; - a->arrays[which_array][array_pos] = value; - return 0; -} - -void* amap_get(amap_s *a, const long position) -{ - if (position >= a->size) - return NULL; - int which_array = position / AMAP_MAX_ARRAY_LENGTH; - int array_pos = position % AMAP_MAX_ARRAY_LENGTH; - return a->arrays[which_array][array_pos]; -} - -void* amap_unset(amap_s *a, const long position) -{ - if (position >= a->size) - return NULL; - int which_array = position / AMAP_MAX_ARRAY_LENGTH; - int array_pos = position % AMAP_MAX_ARRAY_LENGTH; - void *value = a->arrays[which_array][array_pos]; - a->arrays[which_array][array_pos] = NULL; - return value; -} - -void amap_run_cb(amap_s *a, void (*cb)(void *data)) -{ - for (int i = 0; i < a->num_arrays; ++i) { - for (int j = 0; j < AMAP_MAX_ARRAY_LENGTH; ++j) { - if (a->arrays[i][j]) - cb(a->arrays[i][j]); - } - } -} - -void amap_print(amap_s* a) -{ - Put("amap_s (%p):", (void*)a); - Put("\tmmapped: %d", a->mmapped); - Put("\tmax_array_length: %d", AMAP_MAX_ARRAY_LENGTH); - Put("\tnum_arrays: %d", a->num_arrays); - Put("\tsize: %lu", a->size); - Out("\toccupied slots: "); - for (int i = 0; i < a->num_arrays; ++i) { - for (int j = 0; j < AMAP_MAX_ARRAY_LENGTH; ++j) { - if (a->arrays[i][j] != NULL) { - Out("%d:%d ", i, j); - } - } - } - Out("\n"); -} - -void _amap_test(amap_s *a) -{ - assert(0 == amap_set(a, 0, (void*)10)); - assert(0 == amap_set(a, 1, (void*)11)); - assert(0 == amap_set(a, 2, (void*)12)); - assert(0 == amap_set(a, 3, (void*)a)); - assert(10 == (long) amap_get(a, 0)); - assert(11 == (long) amap_get(a, 1)); - assert(12 == (long) amap_get(a, 2)); - assert(a == amap_get(a, 3)); - - assert(0 == amap_set(a, AMAP_MAX_ARRAY_LENGTH-1, (void*) 23)); - assert(23 == (long) amap_get(a, AMAP_MAX_ARRAY_LENGTH-1)); - - assert(0 == amap_set(a, AMAP_MAX_ARRAY_LENGTH, (void*) 42)); - assert(42 == (long) amap_get(a, AMAP_MAX_ARRAY_LENGTH)); - - assert(0 == amap_set(a, AMAP_MAX_ARRAY_LENGTH*2-1, (void*) (23+42))); - assert(42+23 == (long) amap_get(a, AMAP_MAX_ARRAY_LENGTH*2-1)); - assert(0 == amap_set(a, AMAP_MAX_ARRAY_LENGTH*2, (void*) 23)); - - - assert(NULL == amap_get(a, 1024*1024*9-1)); - assert(0 == amap_set(a, 1024*1024*9-1, (void*) 0x1)); - assert(0x1 == (long) amap_get(a, 1024*1024*9-1)); - assert(0x1 == (long) amap_unset(a, 1024*1024*9-1)); - assert(NULL == amap_get(a, 1024*1024*9-1)); - - assert(0 == amap_set(a, 1024*1024*9, (void*) 100)); - assert(100 == (long) amap_get(a, 1024*1024*9)); - - assert(0 == amap_set(a, 1024*1024*9+1, (void*) 101)); - assert(101 == (long) amap_get(a, 1024*1024*9+1)); - - assert(0 == amap_set(a, 1024*1024*10-2, (void*) 102)); - assert(102 == (long) amap_get(a, 1024*1024*10-2)); - - assert(0 == amap_set(a, 1024*1024*10-1, a)); - assert(a == amap_get(a, 1024*1024*10-1)); - //amap_print(a); - - assert(a == amap_unset(a, 1024*1024*10-1)); - assert(a != amap_unset(a, 1024*1024*10-1)); - //amap_print(a); -} - -void amap_test(void) -{ - // First test the non-mmapped version - amap_s* a = amap_new(1024*1024*10); - _amap_test(a); - amap_destroy(a); - - // Now test the mapped version - a = amap_new_mmapped(1024*1024*10); - _amap_test(a); - amap_destroy(a); - - // Another test with non-alligned size - a = amap_new(1024*1024*10+1); - _amap_test(a); - amap_destroy(a); -} - diff --git a/ioreplay/src/datas/amap.h b/ioreplay/src/datas/amap.h deleted file mode 100644 index 882a7c5..0000000 --- a/ioreplay/src/datas/amap.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef AMAP_H -#define AMAP_H - -#include "../defaults.h" - -#define AMAP_MAX_ARRAY_LENGTH 1024*8 - -/** - * @brief Implements an array map data structure - * - * This array map can hold a HUGE amount of entries by allocating multiple - * smaller arrays. There are two version of the amap data structure available: - * a memory mapped (mmap) and a normal version. The memory mapped version can - * be used for IPC between various processes. - */ -typedef struct amap_s_ { - void*** arrays; /**< The pointers to the amap arrays */ - int num_arrays; /**< The amount of arrays used in the amap */ - long size; /**< The total size/capacity of the amap */ - bool mmapped; /**< True if amap is memory mapped */ - void (*data_destroy)(void *data); /**< Callback to destroy all elements */ -} amap_s; - -amap_s* amap_new(const long size); -amap_s* amap_new_mmapped(const long size); -int amap_set(amap_s *a, const long position, void* value); -void* amap_get(amap_s *a, const long position); -void* amap_unset(amap_s *a, const long position); -void amap_print(amap_s *a); -void amap_destroy(amap_s *a); -void amap_reset(amap_s *a); -void amap_run_cb(amap_s *a, void (*cb)(void *data)); -void amap_test(void); - -#endif // AMAP_H diff --git a/ioreplay/src/datas/btree.c b/ioreplay/src/datas/btree.c deleted file mode 100644 index da5da48..0000000 --- a/ioreplay/src/datas/btree.c +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "btree.h" - -btree_s* btree_new() -{ - btree_s *b = Malloc(btree_s); - *b = (btree_s) { - .root = NULL, .size = 0 - }; - return b; -} - -void btree_destroy(btree_s* b) -{ - if (b->root) - btreelem_destroy_r(b->root); - free(b); -} - -void btree_destroy2(btree_s* b) -{ - if (b->root) - btreelem_destroy_r2(b->root); - free(b); -} - -int btree_insert(btree_s* b, int key, void *data) -{ - int ret = 1; - - if (b->root == NULL) { - b->root = btreelem_new(key, data); - ret = 0; - } else { - ret = btreelem_insert_r(b->root, key, data); - } - - if (ret == 0) { - b->size++; - } - - return ret; -} - -void* btree_get(btree_s* b, int key) -{ - if (b->root == NULL) - return NULL; - - return btreelem_get_r(b->root, key); -} - -void btree_print(btree_s* b) -{ - btreelem_print_r(b->root, 0); -} - -btreelem_s* btreelem_new(int key, void *data) -{ - btreelem_s *e = Malloc(btreelem_s); - *e = (btreelem_s) { - .key = key, .data = data, .left = NULL, .right = NULL - }; - return e; -} - -void btreelem_destroy_r(btreelem_s* e) -{ - if (e->left) { - btreelem_destroy_r(e->left); - } - if (e->right) { - btreelem_destroy_r(e->right); - } - - free(e); -} - -void btreelem_destroy_r2(btreelem_s* e) -{ - if (e->left) - btreelem_destroy_r(e->left); - if (e->right) - btreelem_destroy_r(e->right); - if (e->data) - btree_destroy(e->data); - - free(e); -} - -int btreelem_insert_r(btreelem_s* e, int key, void *data) -{ - int ret = 0; - - if (e->key == key) { - ret = 1; - } - - else if (e->key > key) { - if (e->left == NULL) { - e->left = btreelem_new(key, data); - } else { - ret = btreelem_insert_r(e->left, key, data); - } - } - - else { - if (e->right == NULL) { - e->right = btreelem_new(key, data); - } else { - ret = btreelem_insert_r(e->right, key, data); - } - } - - return ret; -} - -void* btreelem_get_r(btreelem_s* e, int key) -{ - void *data = NULL; - - if (e->key == key) { - data = e->data; - } - - else if (e->key > key) { - if (e->left) { - data = btreelem_get_r(e->left, key); - } - } - - else { - if (e->right) { - data = btreelem_get_r(e->right, key); - } - } - - return data; -} - -void btreelem_print_r(btreelem_s* e, int depth) -{ - for (int i = 0; i < depth; ++i) { - Out(" "); - } - Put("%d\n", e->key); - - if (e->left) { - btreelem_print_r(e->left, depth); - } - - if (e->right) { - btreelem_print_r(e->right, depth+1); - } -} - diff --git a/ioreplay/src/datas/btree.h b/ioreplay/src/datas/btree.h deleted file mode 100644 index 55da560..0000000 --- a/ioreplay/src/datas/btree.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef BTREE_H -#define BTREE_H - -#include "../defaults.h" - -/** - * @brief This defines an element of the binary tree data structure - */ -typedef struct btreelem_ { - struct btreelem_ *left; /**< The next element to the left */ - struct btreelem_ *right; /**< The next element to the right */ - int key; /**< The key of the element */ - void *data; /**< A pointer to the data stored in this element */ -} btreelem_s; - -/** - * @brief This defines a binary tree data structure. - */ -typedef struct btree_s_ { - btreelem_s *root; /**< The root element */ - int size; /**< The current size of the binary tree */ -} btree_s; - -btree_s* btree_new(); -void btree_destroy(btree_s *b); -void btree_destroy2(btree_s *b); -int btree_insert(btree_s *b, int key, void *data); -void* btree_get(btree_s *b, int key); -void btree_print(btree_s *b); - -btreelem_s* btreelem_new(int key, void *data); -void btreelem_destroy_r(btreelem_s *e); -void btreelem_destroy_r2(btreelem_s *e); -int btreelem_insert_r(btreelem_s *e, int key, void *data); -void* btreelem_get_r(btreelem_s *e, int key); -void btreelem_print_r(btreelem_s *e, int depth); - -#endif // BTREE_H diff --git a/ioreplay/src/datas/hmap.c b/ioreplay/src/datas/hmap.c deleted file mode 100644 index 96c373e..0000000 --- a/ioreplay/src/datas/hmap.c +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "hmap.h" - -#define _Using_string_keys h->keys != NULL - -unsigned int hmap_get_addr(hmap_s *h, char *key) -{ - unsigned long hash = 5381; - int len = strlen(key); - - for (int i = 0; i < len; ++i) { - hash = ((hash << 5) + hash) + key[i]; /* hash * 33 + c */ - } - - return (unsigned int) (hash % h->size); -} - -unsigned int hmap_get_addr_l(hmap_s *h, const long key) -{ - return (unsigned int) (key % h->size); -} - -hmap_s *_hmap_new(unsigned int init_size) -{ - hmap_s *h = Malloc(hmap_s); - - h->size = init_size; - h->data = Calloc(init_size, void*); - h->l = Calloc(init_size, list_s*); - h->data_destroy = NULL; - h->keys = NULL; - h->keys_l = NULL; - - Mset(h->data, 0, init_size, void*); - Mset(h->l, 0, init_size, list_s*); - - return h; -} - -hmap_s *hmap_new(unsigned int init_size) -{ - hmap_s *h = _hmap_new(init_size); - h->keys = Calloc(init_size, char*); - Mset(h->keys, 0, init_size, char*); - - return h; -} - -hmap_s *hmap_new_l(unsigned int init_size) -{ - hmap_s *h = _hmap_new(init_size); - h->keys_l = Calloc(init_size, int); - Mset(h->keys_l, -1, init_size, int); - - return h; -} - -void hmap_destroy(hmap_s *h) -{ - for (int i = 0; i < h->size; ++i) { - if (h->l[i]) { - list_s *l = h->l[i]; - if (h->data_destroy) - l->data_destroy = h->data_destroy; - list_destroy(h->l[i]); - } - if (h->data[i] && h->data_destroy) { - h->data_destroy(h->data[i]); - } - } - - free(h->data); - if (h->keys) - free(h->keys); - if (h->keys_l) - free(h->keys_l); - free(h->l); - free(h); - - return; -} - -int hmap_insert(hmap_s *h, char *key, void *data) -{ - if (data == NULL) { - Error("insert data can not be NULL"); - } - - int addr = hmap_get_addr(h, key); - - if (h->data[addr]) { - - if (strcmp(key, h->keys[addr]) == 0) { - // Key already exists - return 0; - } - - // There is already data, collision, create a linked list - list_s *l = h->l[addr] = list_new(); - list_key_insert(l, h->keys[addr], h->data[addr]); - list_key_insert(l, key, data); - - // Not needed anymore, as the elements are in the linked list now. - free(h->keys[addr]); - h->data[addr] = h->keys[addr] = NULL; - - return 1; - - } else if (h->l[addr]) { - // There was a collision at this address before. Insert - // the element to the linked list. Returns 0 if key is already - // in the list (no additional insert made) or 1 otherwise. - return list_key_insert(h->l[addr], key, data); - } - - // New entry on a collision free address - h->data[addr] = data; - h->keys[addr] = Clone(key); - - return 1; -} - -int hmap_insert_l(hmap_s *h, const long key, void *data) -{ - if (data == NULL) { - Error("insert data can not be NULL"); - } - - int addr = hmap_get_addr_l(h, key); - - if (h->data[addr]) { - - if (key == h->keys_l[addr]) { - // Key already exists - return 0; - } - - // There is already data, collision, create a linked list - list_s *l = h->l[addr] = list_new_l(); - list_key_insert_l(l, h->keys_l[addr], h->data[addr]); - list_key_insert_l(l, key, data); - - // Not needed anymore, as the elements are in the linked list now. - h->data[addr] = NULL; - h->keys_l[addr] = -1; - - return 1; - - } else if (h->l[addr]) { - // There was a collision at this address before. Insert - // the element to the linked list. Returns 0 if key is already - // in the list (no additional insert made) or 1 otherwise. - return list_key_insert_l(h->l[addr], key, data); - } - - // New entry on a collision free address - h->data[addr] = data; - h->keys_l[addr] = key; - - return 1; -} - -void* hmap_remove(hmap_s *h, char *key) -{ - int addr = hmap_get_addr(h, key); - - if (h->data[addr] != NULL) { - void *data = h->data[addr]; - free(h->keys[addr]); - h->data[addr] = h->keys[addr] = NULL; - return data; - - } else if (h->l[addr] != NULL) { - // There was a collision at this address before. Remove - // the element to the linked list. Returns the object if key is - // already in the list (no additional insert made) or NULL - // otherwise. - return list_key_remove(h->l[addr], key); - } - - // Key is not present - return NULL; -} - -void* hmap_remove_l(hmap_s *h, const long key) -{ - int addr = hmap_get_addr_l(h, key); - - if (h->data[addr] != NULL) { - void *data = h->data[addr]; - h->data[addr] = NULL; - h->keys_l[addr] = -1; - return data; - - } else if (h->l[addr] != NULL) { - // There was a collision at this address before. Remove - // the element to the linked list. Returns the object if key is - // already in the list (no additional insert made) or NULL - // otherwise. - return list_key_remove_l(h->l[addr], key); - } - - // Key is not present - return NULL; -} - -void* hmap_get(hmap_s *h, char *key) -{ - int addr = hmap_get_addr(h, key); - if (h->data[addr] && strcmp(h->keys[addr], key) == 0) { - return h->data[addr]; - - } else if (h->l[addr]) { - return list_key_get(h->l[addr], key); - } - - return NULL; -} - -void* hmap_get_l(hmap_s *h, const long key) -{ - int addr = hmap_get_addr_l(h, key); - if (h->data[addr] && h->keys_l[addr] == key) { - return h->data[addr]; - - } else if (h->l[addr]) { - return list_key_get_l(h->l[addr], key); - } - - return NULL; -} - -void hmap_run_cb(hmap_s* h, void (*cb)(void *data)) -{ - for (int i = 0; i < h->size; ++i) { - if (h->l[i]) { - list_s *l = h->l[i]; - list_run_cb(l, cb); - } - if (h->data[i]) { - cb(h->data[i]); - } - } -} - -void hmap_run_cb2(hmap_s* h, void (*cb)(void *data, void *data2), void *data_) -{ - for (int i = 0; i < h->size; ++i) { - if (h->l[i]) { - list_s *l = h->l[i]; - list_run_cb2(l, cb, data_); - } - if (h->data[i]) { - cb(h->data[i], data_); - } - } -} - -void hmap_print(hmap_s *h) -{ - for (int i = 0; i < h->size; ++i) { - if (h->data[i]) { - if (_Using_string_keys) { - Put("hmap:%p addr:%d key:'%s'", (void*)h, i, h->keys[i]); - } else { - Put("hmap:%p addr:%d key:%d", (void*)h, i, h->keys_l[i]); - } - } else if (h->l[i]) { - Put("hmap:%p addr:%d LIST", (void*)h, i); - list_print(h->l[i]); - } - } -} - -static void _hmap_test(hmap_s *h) -{ - void* somedata = (void*)h; - - assert(1 == hmap_insert(h, "someval", (void*)23)); - assert(1 == hmap_insert(h, "another value", (void*)123)); - - assert(1 == hmap_insert(h, "mimecast", somedata)); - assert(0 == hmap_insert(h, "mimecast", somedata)); - assert(1 == hmap_insert(h, "is", somedata)); - assert(1 == hmap_insert(h, "hiring", somedata)); - - assert(NULL != hmap_get(h, "mimecast")); - assert(NULL == hmap_get(h, "Mimecast")); - - assert(NULL != hmap_remove(h, "mimecast")); - assert(NULL == hmap_remove(h, "mimecast")); - - assert(1 == hmap_insert(h, "mimecast", somedata)); - assert(NULL != hmap_get(h, "mimecast")); - - assert(23 == (long)hmap_get(h, "someval")); - assert(23 == (long)hmap_get(h, "someval")); - - assert(123 == (long)hmap_remove(h, "another value")); - assert(0 == (long)hmap_remove(h, "another value")); - assert(NULL == hmap_get(h, "another value")); - - //hmap_print(h); -} - -static void _hmap_test_l(hmap_s *h) -{ - void* somedata = (void*)h; - - assert(1 == hmap_insert_l(h, 1, (void*)23)); - assert(1 == hmap_insert_l(h, 5, (void*)123)); - - assert(1 == hmap_insert_l(h, 3, somedata)); - assert(0 == hmap_insert_l(h, 3, somedata)); - assert(1 == hmap_insert_l(h, 4, somedata)); - assert(1 == hmap_insert_l(h, 6, somedata)); - - assert(NULL != hmap_get_l(h, 3)); - assert(NULL == hmap_get_l(h, 7)); - - assert(NULL != hmap_remove_l(h, 3)); - assert(NULL == hmap_remove_l(h, 3)); - - assert(1 == hmap_insert_l(h, 3, somedata)); - assert(NULL != hmap_get_l(h, 3)); - - assert(23 == (long)hmap_get_l(h, 1)); - assert(23 == (long)hmap_get_l(h, 1)); - - assert(123 == (long)hmap_remove_l(h, 5)); - assert(0 == (long)hmap_remove_l(h, 5)); - assert(NULL == hmap_get_l(h, 5)); -} - -void hmap_test(void) -{ - hmap_s* h = hmap_new(1024); - _hmap_test(h); - hmap_destroy(h); - - h = hmap_new(2); - _hmap_test(h); - hmap_destroy(h); - - h = hmap_new_l(1024); - _hmap_test_l(h); - hmap_print(h); - hmap_destroy(h); -} diff --git a/ioreplay/src/datas/hmap.h b/ioreplay/src/datas/hmap.h deleted file mode 100644 index 9d1978b..0000000 --- a/ioreplay/src/datas/hmap.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef HMAP_H -#define HMAP_H - -#include "../defaults.h" -#include "list.h" - -/** - * @brief A hash map data structure - * - * There are two version of this hmap data structure. One version is utilising - * string keys and the other one is utilising long keys. - * - * On hash collision the data structure will make use of a "named" linked list, - * whereas every member of the linked list has either a string key or a long - * key associated. - */ -typedef struct hmap_s_ { - char **keys; /**< List of all keys, NULL if nothing at a address */ - int *keys_l; /**< Same as keys, but for long keys */ - void **data; /**< Pointers to the stored data, NULL if nothing there */ - list_s **l; /**< Pointers to the linked lists, used on hash collision */ - void (*data_destroy)(void *data); /**< Callback to destroy all data */ - unsigned int size; /**< Size of the hmap */ -} hmap_s; - -hmap_s* hmap_new(unsigned int init_size); -hmap_s* hmap_new_l(unsigned int init_size); -void hmap_destroy(hmap_s* h); -void hmap_run_cb(hmap_s* h, void (*cb)(void *data)); -void hmap_run_cb2(hmap_s* h, void (*cb)(void *data, void *data2), void *data_); -int hmap_insert_l(hmap_s* h, const long key, void *data); -int hmap_insert(hmap_s* h, char* key, void *data); -void* hmap_remove_l(hmap_s* h, const long key); -void* hmap_remove(hmap_s* h, char* key); -void* hmap_get_l(hmap_s* h, const long key); -void* hmap_get(hmap_s* h, char* key); -unsigned int hmap_get_addr_l(hmap_s* h, const long key); -unsigned int hmap_get_addr(hmap_s* h, char* key); -void hmap_print(hmap_s* h); -void hmap_test(void); - -#endif // HMAP_H diff --git a/ioreplay/src/datas/list.c b/ioreplay/src/datas/list.c deleted file mode 100644 index 9cc78db..0000000 --- a/ioreplay/src/datas/list.c +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "list.h" - - -list_s *list_new() -{ - list_s *l = Malloc(list_s); - *l = (list_s) { - .first = NULL, .data_destroy = NULL - }; - return l; -} - -list_s *list_new_l() -{ - return list_new(); -} - -void list_destroy(list_s *l) -{ - list_elem_s *current = l->first; - - while (current) { - if (current->key) - free(current->key); - if (current->data && l->data_destroy) - l->data_destroy(current->data); - list_elem_s *next = current->next; - free(current); - current = next; - } - - free(l); -} - -int list_key_insert(list_s *l, char *key, void *data) -{ - list_elem_s *current = l->first; - - while (current) { - // Already in the list - if (strcmp(current->key, key) == 0) - return 0; - current = current->next; - } - - list_elem_s *e = Malloc(list_elem_s); - - e->prev = NULL; - e->next = l->first; - e->key = Clone(key); - e->key_l = -1; - e->data = data; - - if (l->first) { - l->first->prev = e; - l->first = e; - - } else { - l->first = e; - } - - return 1; -} - -int list_key_insert_l(list_s *l, const long key, void *data) -{ - list_elem_s *current = l->first; - - while (current) { - if (current->key_l == key) - return 0; - current = current->next; - } - - list_elem_s *e = Malloc(list_elem_s); - - e->prev = NULL; - e->next = l->first; - e->key = NULL; - e->key_l = key; - e->data = data; - - if (l->first) { - l->first->prev = e; - l->first = e; - - } else { - l->first = e; - } - - return 1; -} - -void _list_elem_remove(list_s *l, list_elem_s *e) -{ - if (l->first == e) { - list_elem_s *first = e->next; - if (first) - first->prev = NULL; - l->first = first; - - } else { - list_elem_s *prev = e->prev; - list_elem_s *next = e->next; - - prev->next = next; - if (next) - next->prev = prev; - } - - if (e->key) - free(e->key); - free(e); -} - -void* list_key_remove(list_s *l, char *key) -{ - list_elem_s *current = l->first; - - while (current) { - if (strcmp(current->key, key) == 0) { - void *data = current->data; - _list_elem_remove(l, current); - return data; - } - current = current->next; - } - - return NULL; -} - -void* list_key_remove_l(list_s *l, const long key) -{ - list_elem_s *current = l->first; - - while (current) { - if (current->key_l == key) { - void *data = current->data; - _list_elem_remove(l, current); - return data; - } - current = current->next; - } - - return NULL; -} - -void* list_key_get(list_s *l, char *key) -{ - list_elem_s *current = l->first; - - while (current) { - if (strcmp(current->key, key) == 0) - return current->data; - current = current->next; - } - - return NULL; -} - -void* list_key_get_l(list_s *l, const long key) -{ - list_elem_s *current = l->first; - - while (current) { - if (current->key_l == key) - return current->data; - current = current->next; - } - - return NULL; -} - -void list_run_cb(list_s* l, void (*cb)(void *data)) -{ - list_elem_s *current = l->first; - - while (current) { - if (current->data) - cb(current->data); - current = current->next; - } -} - -void list_run_cb2(list_s* l, void (*cb)(void *data, void *data2), void *data_) -{ - list_elem_s *current = l->first; - - while (current) { - if (current->data) - cb(current->data, data_); - current = current->next; - } -} - -void list_print(list_s *l) -{ - list_elem_s *current = l->first; - - while (current) { - if (current->key != NULL) { - Put("list:%p key:'%s' data:%p", (void*)l, - current->key, current->data); - } else { - Put("list:%p key:%ld data:%p", (void*)l, - current->key_l, current->data); - } - current = current->next; - } -} - -void list_test(void) -{ - list_s *l = list_new(); - void* somedata = (void*)l; - - assert(1 == list_key_insert(l, "foo", (void*)1)); - assert(1 == list_key_insert(l, "bar", (void*)2)); - assert(1 == list_key_insert(l, "baz", (void*)3)); - assert(2 == (long)list_key_remove(l, "bar")); - assert(1 == (long)list_key_remove(l, "foo")); - assert(3 == (long)list_key_remove(l, "baz")); - - assert(1 == list_key_insert(l, "I/O replay", somedata)); - assert(1 == list_key_insert(l, "for", somedata)); - assert(1 == list_key_insert(l, "benchmarking your server", somedata)); - assert(0 == list_key_insert(l, "for", somedata)); - - assert(NULL != list_key_get(l, "benchmarking your server")); - assert(NULL == list_key_get(l, "Mimecast")); - - assert(NULL != list_key_remove(l, "benchmarking your server")); - assert(NULL == list_key_remove(l, "benchmarking your server")); - assert(1 == list_key_insert(l, "benchmarking your server", somedata)); - - assert(1 == list_key_insert(l, "MiMecast", (void*)42)); - assert(42 == (long)list_key_get(l, "MiMecast")); - - l = list_new_l(); - - assert(1 == list_key_insert_l(l, 1, (void*)1)); - assert(1 == list_key_insert_l(l, 2, (void*)2)); - assert(1 == list_key_insert_l(l, 3, (void*)3)); - assert(1 == (long)list_key_get_l(l, 1)); - assert(1 == (long)list_key_remove_l(l, 1)); - assert(1 != (long)list_key_remove_l(l, 1)); - assert(3 == (long)list_key_remove_l(l, 3)); - - assert(1 == list_key_insert_l(l, 1234, somedata)); - assert(1 == list_key_insert_l(l, 13, somedata)); - assert(1 == list_key_insert_l(l, 666, somedata)); - assert(0 == list_key_insert_l(l, 13, somedata)); - - assert(NULL != list_key_get_l(l, 666)); - assert(NULL == list_key_get_l(l, 777)); - - assert(NULL != list_key_remove_l(l, 666)); - assert(NULL == list_key_remove_l(l, 666)); - assert(1 == list_key_insert_l(l, 666, somedata)); - - assert(1 == list_key_insert_l(l, 42, (void*)42)); - assert(42 == (long)list_key_get_l(l, 42)); - - //list_print(l); -} diff --git a/ioreplay/src/datas/list.h b/ioreplay/src/datas/list.h deleted file mode 100644 index 385333c..0000000 --- a/ioreplay/src/datas/list.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef LIST_H -#define LIST_H - -#include "../defaults.h" - -/** - * @brief Definition of a linked list element - */ -typedef struct list_elem_s_ { - struct list_elem_s_ *prev; /**< The previous element */ - struct list_elem_s_ *next; /**< The next element */ - char *key; /**< The key of the lemenet */ - long key_l; /**< The same as key, but for long keys */ - void *data; /**< Pointer to the stored data */ -} list_elem_s; - -/** - * @brief Definition of a named linked list data structure - * - * There are two version of this list data structure. One version is utilising - * string keys and the other one is utilising long keys. - */ -typedef struct list_s_ { - list_elem_s *first; /**< The first element, NULL if list empty */ - void (*data_destroy)(void *data); /**< Callback to destroy all data */ -} list_s; - -list_s* list_new(); -list_s* list_new_l(); -void list_destroy(list_s* l); -void list_run_cb(list_s* l, void (*cb)(void *data)); -void list_run_cb2(list_s* l, void (*cb)(void *data, void *data2), void *data_); -int list_key_insert(list_s* l, char *key, void *data); -int list_key_insert_l(list_s* l, const long key, void *data); -void* list_key_remove(list_s* l, char *key); -void* list_key_remove_l(list_s* l, const long key); -void* list_key_get(list_s* l, char *key); -void* list_key_get_l(list_s* l, const long key); -void list_print(list_s* l); -void list_test(); - -#endif // LIST_H diff --git a/ioreplay/src/datas/rbuffer.c b/ioreplay/src/datas/rbuffer.c deleted file mode 100644 index c019e6c..0000000 --- a/ioreplay/src/datas/rbuffer.c +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "rbuffer.h" - -rbuffer_s *rbuffer_new(const int size) -{ - rbuffer_s *r = Malloc(rbuffer_s); - - r->size = size; - r->read_pos = size-1; - r->write_pos = 0; - r->ring = Calloc(size, void*); - - Mset(r->ring, 0, size, void*); - - return r; -} - -void rbuffer_destroy(rbuffer_s *r) -{ - if (r) { - free(r->ring); - free(r); - } -} - -bool rbuffer_insert(rbuffer_s* r, void *data) -{ - if (r->write_pos == r->read_pos) - // Ring buffer is full - return false; - - r->ring[r->write_pos] = data; - r->write_pos = (r->write_pos+1) % r->size; - - return true; -} - -bool rbuffer_has_next(rbuffer_s* r) -{ - sig_atomic_t read_pos = (r->read_pos+1) % r->size; - - if (read_pos == r->write_pos) - // No more items to read, buffer is empty - { - return false; - } - - return true; -} - -void* rbuffer_get_next(rbuffer_s* r) -{ - sig_atomic_t read_pos = (r->read_pos+1) % r->size; - - if (read_pos == r->write_pos) - // No more items to read, buffer is empty - { - return NULL; - } - - void *data = r->ring[read_pos]; - r->ring[read_pos] = NULL; - r->read_pos = read_pos; - - return data; -} - -void rbuffer_print(rbuffer_s* r) -{ - Put("rbuffer_s (%p):", (void*)r); - Put("\tsize: %d", (int)r->size); - Put("\tread_pos: %d", r->read_pos); - Put("\twrite_pos: %d", r->write_pos); - Out("\toccupied slots: "); - for (int i = 0; i < r->size; ++i) - if (r->ring[i]) { - Out("%d:%p ", i, r->ring[i]); - } - Out("\n"); -} - -void rbuffer_test(void) -{ - rbuffer_s *r = rbuffer_new(5); - assert(NULL == rbuffer_get_next(r)); - - assert(rbuffer_insert(r, (void*)1)); - assert(rbuffer_insert(r, (void*)2)); - assert(rbuffer_insert(r, (void*)3)); - assert(rbuffer_insert(r, (void*)4)); - assert(!rbuffer_insert(r, (void*)5)); - rbuffer_print(r); - - assert(rbuffer_has_next(r)); - assert(1 == (long) rbuffer_get_next(r)); - assert(2 == (long) rbuffer_get_next(r)); - assert(3 == (long) rbuffer_get_next(r)); - assert(4 == (long) rbuffer_get_next(r)); - assert(!rbuffer_has_next(r)); - assert(NULL == rbuffer_get_next(r)); - - assert(rbuffer_insert(r, (void*)1)); - assert(1 == (long) rbuffer_get_next(r)); - assert(rbuffer_insert(r, (void*)2)); - assert(2 == (long) rbuffer_get_next(r)); - assert(rbuffer_insert(r, (void*)3)); - assert(3 == (long) rbuffer_get_next(r)); - assert(rbuffer_insert(r, (void*)4)); - assert(4 == (long) rbuffer_get_next(r)); - assert(rbuffer_insert(r, (void*)5)); - assert(5 == (long) rbuffer_get_next(r)); - assert(NULL == rbuffer_get_next(r)); - rbuffer_print(r); - - assert(rbuffer_insert(r, (void*)1)); - rbuffer_print(r); - assert(rbuffer_insert(r, (void*)2)); - assert(1 == (long) rbuffer_get_next(r)); - rbuffer_print(r); - assert(rbuffer_insert(r, (void*)3)); - assert(2 == (long) rbuffer_get_next(r)); - rbuffer_print(r); - assert(rbuffer_insert(r, (void*)4)); - assert(3 == (long) rbuffer_get_next(r)); - rbuffer_print(r); - assert(rbuffer_insert(r, (void*)5)); - rbuffer_print(r); - assert(4 == (long) rbuffer_get_next(r)); - rbuffer_print(r); - assert(5 == (long) rbuffer_get_next(r)); - assert(NULL == rbuffer_get_next(r)); - - rbuffer_destroy(r); -} diff --git a/ioreplay/src/datas/rbuffer.h b/ioreplay/src/datas/rbuffer.h deleted file mode 100644 index fa634de..0000000 --- a/ioreplay/src/datas/rbuffer.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef RBUFFER_H -#define RBUFFER_H - -#include "signal.h" - -#include "../defaults.h" - -/** - * @brief An atomic ring buffer data type definition - * - * This data structure can be used for the common producer/consumer problem. - * As long as there is only max one producer thread and max one consumer thread - * it can be used without any mutex locking. All the operations are atomic. - */ -typedef struct rbuffer_s_ { - /** - * The positions are atomic, means the ring buffer can be accessed from - * multiple threads concurrently (one producer and one consumer thread). - * This is the current read position. - */ - sig_atomic_t read_pos; - /** - * This is the current write position. - */ - sig_atomic_t write_pos; - /** - * Holds the pointers to the actual ring data stored in the ring buffer - */ - void **ring; - /** - * Determines how many elements the ring buffer can hold. The capacity - * will be size-1 though, as we need one empty slot. - */ - int size; -} rbuffer_s; - -/** - * @brief Creates a new ring buffer - * - * @param size The size of the ring buffer - * @return The new ring buffer object - */ -rbuffer_s* rbuffer_new(const int size); - -/** - * @brief Destroys a ring buffer - * - * @param r The ring buffer object - */ -void rbuffer_destroy(rbuffer_s* r); - -/** - * @brief Inserts data pointer to the ring buffer - * - * @param r The ring buffer object - * @param data The data pointer - */ -bool rbuffer_insert(rbuffer_s* r, void *data); - -/** - * @brief Determines whether there is any data in the ring buffer - * - * @param r The ring buffer object - * @return True if there is any data, false otherwise - */ -bool rbuffer_has_next(rbuffer_s* r); - -/** - * @brief Returns and removes the next element from the ring buffer - * - * @param r The ring buffer object - * @return The data pointer - */ -void* rbuffer_get_next(rbuffer_s* r); - -/** - * @brief Prints a ring buffer - * - * @param r The ring buffer object - */ -void rbuffer_print(rbuffer_s* r); - -/** - * @brief Unit tests the ring buffer - */ -void rbuffer_test(void); - -#endif // RBUFFER_H diff --git a/ioreplay/src/datas/stack.c b/ioreplay/src/datas/stack.c deleted file mode 100644 index 94e83e3..0000000 --- a/ioreplay/src/datas/stack.c +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "stack.h" - - -stack_s *stack_new() -{ - stack_s *s = Malloc(stack_s); - *s = (stack_s) { - .top = NULL, .size = 0 - }; - return s; -} - -void stack_destroy(stack_s *s) -{ - stack_elem_s *current = s->top; - - while (current) { - stack_elem_s *next = current->next; - free(current); - current = next; - } - - free(s); -} - -void stack_push(stack_s *s, void *data) -{ - stack_elem_s *new_top = Malloc(stack_elem_s); - - *new_top = (stack_elem_s) { - .next = s->top, - .data = data - }; - - s->top = new_top; - s->size++; -} - -void* stack_pop(stack_s *s) -{ - if (s->top == NULL) { - return NULL; - } - - stack_elem_s *old_top = s->top; - - void *data = old_top->data; - s->top = old_top->next; - free(old_top); - s->size--; - - return data; -} - -int stack_is_empty(stack_s *s) -{ - return s->top == NULL; -} - -stack_s* stack_new_reverse_from(stack_s *s) -{ - stack_s* r = stack_new(); - - while (!stack_is_empty(s)) { - stack_push(r, stack_pop(s)); - } - - stack_destroy(s); - - return r; -} diff --git a/ioreplay/src/datas/stack.h b/ioreplay/src/datas/stack.h deleted file mode 100644 index 87e0974..0000000 --- a/ioreplay/src/datas/stack.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2018 Mimecast Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef STACK_H -#define STACK_H - -#include "../defaults.h" - -/** - * @brief Definition of a stack element - */ -typedef struct stack_elem_s_ { - struct stack_elem_s_ *next; /**< The next element */ - void *data; /**< Pointer to the stored data in the current element */ -} stack_elem_s; - -/** - * @brief Definition of a stack data structure - */ -typedef struct stack_s_ { - stack_elem_s *top; /**< The top element of the stack, NULL if empty */ - unsigned long size; /**< A count how many elements are in the stack */ -} stack_s; - -stack_s* stack_new(); -stack_s* stack_new_reverse_from(stack_s* s); -void stack_destroy(stack_s* s); -void stack_push(stack_s* s, void *data); -void* stack_pop(stack_s* s); -int stack_is_empty(stack_s* s); - -#endif // STACK_H |
