summaryrefslogtreecommitdiff
path: root/ioreplay/src/datas/list.c
diff options
context:
space:
mode:
Diffstat (limited to 'ioreplay/src/datas/list.c')
-rw-r--r--ioreplay/src/datas/list.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/ioreplay/src/datas/list.c b/ioreplay/src/datas/list.c
new file mode 100644
index 0000000..9cc78db
--- /dev/null
+++ b/ioreplay/src/datas/list.c
@@ -0,0 +1,279 @@
+// 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);
+}