BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 74ee43c3216e1f3c3b33a2b6afe70b52b62e5465 / object / list.c

// Related

Nucleus

Barry Ordered object lists 74ee43c (3 years, 2 months ago)
diff --git a/object/list.c b/object/list.c
index e1b2d08..914a303 100644
--- a/object/list.c
+++ b/object/list.c
@@ -6,6 +6,7 @@
  * routines to be used on them.
  */
 
+#include <stdarg.h>
 #include <nucleus/object.h>
 #include <nucleus/memory.h>
 #include <nucleus/panic.h>
@@ -20,6 +21,8 @@ struct ObjectList {
 	struct ListEntry *start, *end;
 	size_t entries;
 	ObjectType *type;
+	enum ListMode mode;
+	compare_callback_t compare;
 	Spinlock lock;
 };
 /* Iterator */
@@ -35,11 +38,20 @@ void release(Spinlock *lock);
 
 /* Create an Object List */
 ObjectList *
-create_list(ObjectType *type)
+create_list(ObjectType *type, enum ListMode mode, ...)
 {
 	ObjectList *list = kmalloc(sizeof(ObjectList));
 	init_lock(&list->lock);
 	list->type = type;
+	list->mode = mode;
+
+	if (mode == LIST_ORDERED) {
+		va_list args;
+		va_start(args, mode);
+		list->compare = va_arg(args, compare_callback_t);
+		va_end(args);
+	}
+
 	return list;
 }
 
@@ -61,15 +73,39 @@ add(ObjectList *list, void *addr)
 		return;
 
 	acquire(&list->lock);
-	struct ListEntry *entry = kmalloc(sizeof(struct ListEntry));
-	if (!list->start)
-		list->start = entry;
-	else
-		list->end->next = entry;
-	entry->prev = list->end;
-	list->end = entry;
+
+	struct ListEntry *entry, *next;
+	entry = kmalloc(sizeof(struct ListEntry));
 	entry->obj = get(obj);
 	list->entries++;
+
+	if (!list->start) {
+		/* Only item in list */
+		list->start = list->end = entry;
+	} else if (list->compare) {
+		/* Find next item */
+		for (next = list->start; next; next = next->next) {
+			if (list->compare(next->obj, obj) > 0)
+				break;
+		}
+		if (!next)
+			goto end;
+		/* Add in */
+		entry->prev = next->prev;
+		entry->next = next;
+		next->prev = entry;
+		if (entry->prev)
+			entry->prev->next = entry;
+		else
+			list->start = entry;
+	} else {
+end:
+		/* Add to end of list */
+		list->end->next = entry;
+		entry->prev = list->end;
+		list->end = entry;
+	}
+
 	release(&list->lock);
 }
 
@@ -172,7 +208,8 @@ get_nth_item(ObjectList *list, off_t n)
 ObjectList *
 copy_list(ObjectList *list)
 {
-	ObjectList *newlist = create_list(list->type);
+	ObjectList *newlist = create_list(list->type, list->mode,
+	                                  list->compare);
 	acquire(&list->lock);
 	struct ListEntry *entry;
 	for (entry = list->start; entry; entry = entry->next)