Skip to content

Commit

Permalink
Merge pull request #45 from fritzprix/0.2.1
Browse files Browse the repository at this point in the history
0.2.1
  • Loading branch information
fritzprix authored Jul 21, 2018
2 parents 8c1221a + 937c9b8 commit 0438929
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 17 deletions.
3 changes: 3 additions & 0 deletions include/cdsl_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ extern "C" {
#define DECLARE_PRINTER(fn) void fn(void* node)
#endif

/**!
*
*/
typedef void* (*cdsl_generic_compare_t)(void*, void*);
typedef void (*cdsl_generic_printer_t) (void*);
typedef void* (*cdsl_alloc_t)(unsigned long sz);
Expand Down
17 changes: 10 additions & 7 deletions include/cdsl_dlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,25 @@
#define CDSL_DLIST_H_

#include "base_list.h"
#include "sort.h"

#if defined(__cplusplus)
extern "C" {
#endif


#define cdsl_dlistIsEmpty(lhead) (((dlistEntry_t*) lhead)->head== NULL)
#define cdsl_dlistIsEmpty(lhead) (((dlistEntry_t*) lhead)->head== NULL)

#define cdsl_dlistSize(lentry) cdsl_listSize((listEntry_t*) lentry)
#define cdsl_dlistContain(lentry, item) cdsl_listContain((listEntry_t*) lentry, (listNode_t*) item)
#define cdsl_dlistPrint(lentry,print) cdsl_listPrint((listEntry_t*) lentry, print)
#define cdsl_dlistSize(lentry) cdsl_listSize((listEntry_t*) lentry)
#define cdsl_dlistContain(lentry, item) cdsl_listContain((listEntry_t*) lentry, (listNode_t*) item)
#define cdsl_dlistPrint(lentry,print) cdsl_listPrint((listEntry_t*) lentry, print)


#define cdsl_dlistIterInit(lentry, iter) cdsl_iterInit((listEntry_t*) lentry, iter)
#define cdsl_dlistIterHasNext(iter) cdsl_iterHasNext(iter)
#define cdsl_dlistIterNext(iter) cdsl_iterNext(iter)
#define cdsl_dlistIterInit(lentry, iter) cdsl_iterInit((listEntry_t*) lentry, iter)
#define cdsl_dlistIterHasNext(iter) cdsl_iterHasNext(iter)
#define cdsl_dlistIterNext(iter) cdsl_iterNext(iter)

#define cdsl_dlistSort(lentry, order, compare) cdsl_listMergeSort((listEntry_t*) lentry, order, compare, TRUE)

typedef struct cdsl_dlnode dlistNode_t;
typedef struct cdsl_dlentry dlistEntry_t;
Expand Down
17 changes: 10 additions & 7 deletions include/cdsl_slist.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@
#define CDSL_SLIST_H_

#include "base_list.h"
#include "sort.h"

#if defined(__cplusplus)
extern "C" {
#endif


#define cdsl_slistIsEmpty(node) (((slistEntry_t*) node)->head == NULL)
#define cdsl_slistIsEmpty(node) (((slistEntry_t*) node)->head == NULL)

#define cdsl_slistSize(lentry) cdsl_listSize((listEntry_t*) lentry)
#define cdsl_slistContain(lentry, item) cdsl_listContain((listEntry_t*) lentry, (listNode_t*) item)
#define cdsl_slistPrint(lentry,print) cdsl_listPrint((listEntry_t*) lentry, print)
#define cdsl_slistSize(lentry) cdsl_listSize((listEntry_t*) lentry)
#define cdsl_slistContain(lentry, item) cdsl_listContain((listEntry_t*) lentry, (listNode_t*) item)
#define cdsl_slistPrint(lentry,print) cdsl_listPrint((listEntry_t*) lentry, print)

#define cdsl_slistIterInit(lentry, iter) cdsl_iterInit((listEntry_t*) lentry, iter)
#define cdsl_slistIterHasNext(iter) cdsl_iterHasNext(iter)
#define cdsl_slistIterNext(iter) cdsl_iterNext(iter)
#define cdsl_slistSort(lentry, order, compare) cdsl_listMergeSort((listEntry_t*) lentry, order, compare, FALSE)

#define cdsl_slistIterInit(lentry, iter) cdsl_iterInit((listEntry_t*) lentry, iter)
#define cdsl_slistIterHasNext(iter) cdsl_iterHasNext(iter)
#define cdsl_slistIterNext(iter) cdsl_iterNext(iter)

typedef struct cdsl_slnode slistNode_t;
typedef struct cdsl_slentry slistEntry_t;
Expand Down
29 changes: 29 additions & 0 deletions include/sort.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@


#ifndef __CDSL_SORT_C
#define __CDSL_SORT_C

#ifdef __cplusplus
extern "C" {
#endif

#include "base_list.h"

typedef enum {
ASC,
DESC
}sortOrder_t;
/**
* @return positive if one is larger than the_other, or negative otherwise. 0 when the two are exactly same
*/
typedef int (*cdsl_comparator_t)(void* one, void* the_other);

extern void cdsl_listMergeSort(listEntry_t* entry, sortOrder_t order, cdsl_comparator_t comp, BOOL isDoubleLink);

#ifdef __cplusplus
}
#endif



#endif
3 changes: 2 additions & 1 deletion source/base_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ listNode_t* cdsl_iterNext(listIter_t* iter)
return NULL;
if(!iter->prev)
iter->prev = (listNode_t*) iter->entry;
return iter->prev->next;
iter->prev = iter->prev->next;
return iter->prev;
}

listNode_t* cdsl_iterRemove(listIter_t* iter)
Expand Down
3 changes: 2 additions & 1 deletion source/recipe.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ OBJ-y+= base_list\
cdsl_spltree\
cdsl_rbtree\
cdsl_hashtree\
baremetal
baremetal\
sort


85 changes: 85 additions & 0 deletions source/sort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@



#include "cdsl_dlist.h"
#include "sort.h"


static listNode_t* merge_sort_rc(listNode_t* head, sortOrder_t order, cdsl_comparator_t comp, BOOL isDouble);
static listNode_t* peek_middle(listNode_t* head);

extern void cdsl_listMergeSort(listEntry_t* entry, sortOrder_t order, cdsl_comparator_t comp, BOOL isDoubleLink) {
entry->head = merge_sort_rc(entry->head, order, comp, isDoubleLink);
}

static listNode_t* merge_sort_rc(listNode_t* head, sortOrder_t order, cdsl_comparator_t comp, BOOL isDouble) {
if(!(head->next)) {
return head;
}
listNode_t* middle = peek_middle(head);
if(!middle) {
return head;
}
listNode_t* left_cur, *right_cur;
if(head->next == middle) {
head->next = NULL;
left_cur = head;
right_cur = merge_sort_rc(middle, order, comp, isDouble);
} else {
right_cur = merge_sort_rc(middle->next, order, comp, isDouble);
middle->next = NULL;
left_cur = merge_sort_rc(head, order, comp, isDouble);
}
head = NULL;
listNode_t** slot = &head;
// keep
// NOTE : middle used as previous from this point
middle = NULL;
while(!((left_cur == NULL) && (right_cur == NULL))) {

if ((left_cur != NULL) && (right_cur != NULL)) {
if (comp(left_cur, right_cur) > 0) {
*slot = (order == ASC)? right_cur : left_cur;
} else {
*slot = (order == ASC)? left_cur : right_cur;
}
} else if (left_cur == NULL) {
*slot = right_cur;
} else {
*slot = left_cur;
}
if(*slot == left_cur) {
left_cur = left_cur->next;
} else if(*slot == right_cur) {
right_cur = right_cur->next;
}
if(isDouble) {
if(middle) {
((dlistNode_t*) *slot)->prev = (dlistNode_t*) middle;
middle = *slot;
} else {
middle = *slot;
((dlistNode_t*) middle)->prev = NULL;
}
}
slot = &(*slot)->next;
}
return head;
}

/***
* head node of list chunk to be searched
* @return head if there is only list node in the list chunk, otherwise return middle list node within the list chunk.
*/
static listNode_t* peek_middle(listNode_t* head) {
listNode_t* mid = head;
uint32_t l_cnt = 0;
while(head->next) {
if((l_cnt % 2) == 0) {
mid = mid->next;
}
l_cnt++;
head = head->next;
}
return mid;
}
27 changes: 26 additions & 1 deletion source/test/cdsl_list_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
#include <stdio.h>
#include "cdsl_dlist.h"
#include "cdsl_list_test.h"

#include "sort.h"
struct card {
dlistNode_t list_node;
int num;
};

static DECLARE_COMPARE_FN(compare);
static int compare_sort(void* one, void* the_other);
static struct card cards[TEST_SIZE];

BOOL cdsl_listDoTest(void)
Expand Down Expand Up @@ -45,9 +46,33 @@ BOOL cdsl_listDoTest(void)
}
}

// test sort
for(idx = 0; idx < TEST_SIZE; idx++) {
cdsl_dlistNodeInit(&cards[idx].list_node);
cards[idx].num = idx;
cdsl_dlistPutHead(&list_entry, &(cards[idx].list_node));
}
cdsl_dlistSort(&list_entry, DESC, compare_sort);
listIter_t iter;
cdsl_iterInit((listEntry_t*) &list_entry, &iter);
int prev_num = TEST_SIZE;
while(cdsl_iterHasNext(&iter)) {
void* node = (void*) cdsl_iterNext(&iter);
struct card* cp = container_of(node, struct card, list_node);
if(prev_num < cp->num) {
return FALSE;
}
prev_num = cp->num;
}
return TRUE;
}

static int compare_sort(void* one, void* the_other) {
struct card* this_card = container_of(one, struct card, list_node);
struct card* that_card = container_of(the_other, struct card, list_node);
return this_card->num - that_card->num;
}


static DECLARE_COMPARE_FN(compare)
{
Expand Down
25 changes: 25 additions & 0 deletions source/test/cdsl_slist_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ typedef struct card {
static card_t Cards[TEST_SIZE];
static DECLARE_COMPARE_FN(card_compare);
static slistEntry_t listEntry;
static int compare_sort(void* one, void* the_other);


BOOL cdsl_slistDoTest(void){
Expand Down Expand Up @@ -57,10 +58,34 @@ BOOL cdsl_slistDoTest(void){
if(!card)
return FALSE;
}
for(i = 0; i < TEST_SIZE; i++) {
cdsl_slistNodeInit(&Cards[i].list_head);
Cards[i].card_num = i;
cdsl_slistPutHead(&listEntry, &Cards[i].list_head);
}
cdsl_slistSort(&listEntry, DESC, compare_sort);
listIter_t iter;
cdsl_iterInit((listEntry_t*) &listEntry, &iter);
int prev_num = TEST_SIZE;
while(cdsl_iterHasNext(&iter)) {
void* node = (void*) cdsl_iterNext(&iter);
struct card* cp = container_of(node, struct card, list_head);
if(prev_num < cp->card_num) {
return FALSE;
}
prev_num = cp->card_num;
}
return TRUE;
}


static int compare_sort(void* one, void* the_other) {
struct card* this_card = container_of(one, struct card, list_head);
struct card* that_card = container_of(the_other, struct card, list_head);
return this_card->card_num - that_card->card_num;
}


static DECLARE_COMPARE_FN(card_compare){
if(!a)
return b;
Expand Down

0 comments on commit 0438929

Please sign in to comment.