Add Makefile, update readme and fix valgrind found leaks

This commit is contained in:
Darko 2015-03-20 21:18:33 +01:00
parent 57e0a96f18
commit 526617cfc9
3 changed files with 69 additions and 2 deletions

25
Makefile Normal file
View file

@ -0,0 +1,25 @@
DEBUG?= -g
CFLAGS?= -O2 -Wall -W -DSDS_ABORT_ON_OOM
CCOPT= $(CFLAGS)
OBJ = main.o skiplist.o x.o
PRGNAME = sl
all: sl
# Deps (use make dep to generate this)
main.o: x.h skiplist.h x.c skiplist.c main.c
x.o: x.c x.h
skiplist.o: x.c x.h skiplist.c skiplist.h
sl: $(OBJ)
$(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ)
.c.o:
$(CC) -c $(CCOPT) $(DEBUG) $(COMPILE_TIME) $<
clean:
rm -rf $(PRGNAME) *.o
dep:
$(CC) -MM *.c

View file

@ -2,3 +2,10 @@ skiplist
=========
Academic example of skip list implementation in C.
To compile just run
.. code:: bash
make

View file

@ -114,6 +114,11 @@ void sl_print(const slist *sl)
#define HEAD 1
#define TAIL 0
/*
* Repeatedly toss a coin until we get tails.
* Denote with i the number of times coin came up heads
* and return it.
*/
int _toss_coin(int maxlevel) {
int i;
int x;
@ -135,14 +140,14 @@ int _toss_coin(int maxlevel) {
}
/*
* Clean top levels with only INFINITY nodes until only one such
* Remove top levels with only INFINITY nodes until only one such
* level exists.
*/
void _sl_clean_top(slist *sl)
{
sl_node *foo;
for (foo = sl->topleft; foo->below != NULL; foo = foo->below) {
for (foo = sl->topleft; foo->below != NULL;) {
if (foo->next->key == KEY_INF_MAX
&& foo->below->next->key == KEY_INF_MAX) {
sl->topleft = foo->below;
@ -150,14 +155,28 @@ void _sl_clean_top(slist *sl)
sl->topleft->above = NULL;
sl->topright->above = NULL;
--sl->maxlevel;
free(foo->data);
free(foo->next);
free(foo);
foo = sl->topleft;
debug("cleaned one level\n");
} else {
break;
}
}
}
/*
* Toss coin and get i.
* If i is greather than or equal to skip list max level then
* add one more level.
* Search for x and find the positions of the items with largest key
* less than x.
* Insert item into each level up to i.
* If key is found then just update its data.
*/
int sl_add(slist *sl, int key, void *data)
{
sl_node *foo;
@ -190,6 +209,9 @@ int sl_add(slist *sl, int key, void *data)
if (foo->below == NULL) {
break;
}
/*
* Save nodes that will be updated with new node.
*/
update[level--] = foo;
foo = foo->below;
}
@ -233,6 +255,14 @@ int sl_add(slist *sl, int key, void *data)
return res;
}
/*
* Start at the top left position.
* At the current position compare key with node's key.
* If key is found then return it.
* If key > node's key then scan forward.
* If key < node's key then drop down.
* If we drop down past the bottom list then return NULL.
*/
sl_node *sl_find(slist *sl, int key)
{
sl_node *foo;
@ -254,6 +284,11 @@ sl_node *sl_find(slist *sl, int key)
return foo;
}
/*
* Search for key and find positions with the key.
* Remove found positions.
* Remove all but one list containing only INFINITY keys.
*/
int sl_remove(slist *sl, int key)
{
sl_node *foo;