[Nagios-checkins] SF.net SVN: nagios:[2079] nagioscore/trunk

ageric at users.sourceforge.net ageric at users.sourceforge.net
Mon Aug 20 16:26:22 UTC 2012


Revision: 2079
          http://nagios.svn.sourceforge.net/nagios/?rev=2079&view=rev
Author:   ageric
Date:     2012-08-20 16:26:22 +0000 (Mon, 20 Aug 2012)
Log Message:
-----------
libnagios: Include the skiplist API in libnagios and link cgi's to it

This means we no longer have to link the skiplist object file
explicitly with either nagios core or the cgi's, so we tuck in the
build infrastructure to make that happen. We also move a few more
Nagios-centrict macros to lnag-utils (TRUE, FALSE, ERROR and OK) to
prevent the skiplist library having to depend on files outside the
lib directory.

While we're at it, we improve a bit on the library and make two
private helpers static and removing their prototypes from the header
file.

Signed-off-by: Andreas Ericsson <ae at op5.se>

Modified Paths:
--------------
    nagioscore/trunk/base/Makefile.in
    nagioscore/trunk/cgi/Makefile.in
    nagioscore/trunk/cgi/trends.c
    nagioscore/trunk/common/objects.c
    nagioscore/trunk/include/common.h
    nagioscore/trunk/lib/Makefile.in
    nagioscore/trunk/lib/libnagios.h
    nagioscore/trunk/lib/lnag-utils.h
    nagioscore/trunk/xdata/xodtemplate.c
    nagioscore/trunk/xdata/xsddefault.c

Added Paths:
-----------
    nagioscore/trunk/lib/skiplist.c
    nagioscore/trunk/lib/skiplist.h

Removed Paths:
-------------
    nagioscore/trunk/common/skiplist.c
    nagioscore/trunk/include/skiplist.h

Modified: nagioscore/trunk/base/Makefile.in
===================================================================
--- nagioscore/trunk/base/Makefile.in	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/base/Makefile.in	2012-08-20 16:26:22 UTC (rev 2079)
@@ -119,7 +119,7 @@
 DDATADEPS=$(DDATALIBS)
 
 
-OBJS=$(BROKER_O) $(SRC_COMMON)/shared.o workers.o checks.o config.o commands.o events.o flapping.o logging.o macros-base.o netutils.o notifications.o sehandlers.o skiplist.o utils.o $(RDATALIBS) $(CDATALIBS) $(ODATALIBS) $(SDATALIBS) $(PDATALIBS) $(DDATALIBS) $(BASEEXTRALIBS) $(SNPRINTF_O)
+OBJS=$(BROKER_O) $(SRC_COMMON)/shared.o workers.o checks.o config.o commands.o events.o flapping.o logging.o macros-base.o netutils.o notifications.o sehandlers.o utils.o $(RDATALIBS) $(CDATALIBS) $(ODATALIBS) $(SDATALIBS) $(PDATALIBS) $(DDATALIBS) $(BASEEXTRALIBS) $(SNPRINTF_O)
 OBJDEPS=$(ODATADEPS) $(ODATADEPS) $(RDATADEPS) $(CDATADEPS) $(SDATADEPS) $(PDATADEPS) $(DDATADEPS) $(BROKER_H)
 
 all: nagios nagiostats
@@ -130,9 +130,6 @@
 macros-base.o: $(SRC_COMMON)/macros.c $(SRC_INCLUDE)/macros.h
 	$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/macros.c
 
-skiplist.o: $(SRC_COMMON)/skiplist.c $(SRC_INCLUDE)/skiplist.h
-	$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/skiplist.c
-
 objects-base.o: $(SRC_COMMON)/objects.c $(SRC_INCLUDE)/objects.h
 	$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/objects.c
 

Modified: nagioscore/trunk/cgi/Makefile.in
===================================================================
--- nagioscore/trunk/cgi/Makefile.in	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/cgi/Makefile.in	2012-08-20 16:26:22 UTC (rev 2079)
@@ -8,6 +8,7 @@
 SRC_COMMON=../common
 SRC_INCLUDE=../include
 SRC_XDATA=../xdata
+SRC_LIB=../lib
 
 prefix=@prefix@
 exec_prefix=@exec_prefix@
@@ -74,9 +75,9 @@
 DDATADEPS=$(DDATALIBS)
 
 # Common CGI functions (includes object and status functions)
-CGILIBS=$(SRC_COMMON)/shared.o getcgi.o cgiutils.o cgiauth.o macros-cgi.o skiplist.o $(SNPRINTF_O) $(ODATALIBS) $(SDATALIBS)
+CGILIBS=$(SRC_COMMON)/shared.o getcgi.o cgiutils.o cgiauth.o macros-cgi.o $(SNPRINTF_O) $(ODATALIBS) $(SDATALIBS) $(SRC_LIB)/libnagios.a
 CGIHDRS=$(SRC_INCLUDE)/config.h $(SRC_INCLUDE)/common.h $(SRC_INCLUDE)/locations.h
-CGIDEPS=$(CGILIBS) $(ODATADEPS) $(SDATADEPS)
+CGIDEPS=$(CGILIBS) $(ODATADEPS) $(SDATADEPS) $(SRC_LIB)/libnagios.a
 
 
 MATHLIBS=-lm
@@ -90,8 +91,8 @@
 
 ######## REQUIRED LIBRARIES ##########
 
-skiplist.o: $(SRC_COMMON)/skiplist.c $(SRC_INCLUDE)/skiplist.h
-	$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/skiplist.c
+$(SRC_LIB)/libnagios.a:
+	$(MAKE) -C $(SRC_LIB)
 
 macros-cgi.o: $(SRC_COMMON)/macros.c $(SRC_INCLUDE)/macros.h
 	$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/macros.c
@@ -211,3 +212,4 @@
 	done
 
 
+.PHONY: libnagios

Modified: nagioscore/trunk/cgi/trends.c
===================================================================
--- nagioscore/trunk/cgi/trends.c	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/cgi/trends.c	2012-08-20 16:26:22 UTC (rev 2079)
@@ -47,7 +47,6 @@
 extern host *host_list;
 extern service *service_list;
 
-#include "../include/skiplist.h"
 extern skiplist *object_skiplists[NUM_OBJECT_SKIPLISTS];
 
 /* archived state types */

Modified: nagioscore/trunk/common/objects.c
===================================================================
--- nagioscore/trunk/common/objects.c	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/common/objects.c	2012-08-20 16:26:22 UTC (rev 2079)
@@ -23,7 +23,6 @@
 #include "../include/config.h"
 #include "../include/common.h"
 #include "../include/objects.h"
-#include "../include/skiplist.h"
 
 #ifdef NSCORE
 #include "../include/nagios.h"

Deleted: nagioscore/trunk/common/skiplist.c
===================================================================
--- nagioscore/trunk/common/skiplist.c	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/common/skiplist.c	2012-08-20 16:26:22 UTC (rev 2079)
@@ -1,556 +0,0 @@
-/************************************************************************
- *
- * SKIPLIST.C - Skiplist functions for use in Nagios event/object lists
- *
- *
- * Notes:
- *
- * These function implement a slightly modified skiplist from that
- * described by William Pugh (ftp://ftp.cs.umd.edu/pub/skipLists/skiplists.pdf).
- * The structures and function were modified to allow the list to act
- * like a priority queue for the Nagios event list/queue(s).  Multiple nodes with
- * the same key value are allowed on the list to accomodate multiple events
- * occurring at the same (second) point in time.  Implemented peek() and pop()
- * functions to allow for quick event queue processing, and a method to delete
- * a specific list item, based on its pointer, rather than its data value.  Again,
- * this is useful for the Nagios event queue.
- *
- * License:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ************************************************************************/
-
-#include "../include/config.h"
-#include "../include/common.h"
-
-#include "../include/skiplist.h"
-
-
-
-skiplist *skiplist_new(int max_levels, float level_probability, int allow_duplicates, int append_duplicates, int (*compare_function)(void *, void *)) {
-	skiplist *newlist = NULL;
-
-	/* alloc memory for new list structure */
-	if((newlist = (skiplist *)malloc(sizeof(skiplist)))) {
-
-		/* initialize levels, etc. */
-		newlist->current_level = 0;
-		newlist->max_levels = max_levels;
-		newlist->level_probability = level_probability;
-		newlist->allow_duplicates = allow_duplicates;
-		newlist->append_duplicates = append_duplicates;
-		newlist->items = 0;
-		newlist->compare_function = compare_function;
-
-		/* initialize head node */
-		newlist->head = skiplist_new_node(newlist, max_levels);
-		}
-
-	return newlist;
-	}
-
-
-int skiplist_insert(skiplist *list, void *data) {
-	skiplistnode **update = NULL;
-	skiplistnode *thisnode = NULL;
-	skiplistnode *nextnode = NULL;
-	skiplistnode *newnode = NULL;
-	int level = 0;
-	int x = 0;
-
-	if(list == NULL || data == NULL) {
-		return SKIPLIST_ERROR_ARGS;
-		}
-
-	/* initialize update vector */
-	if((update = (skiplistnode **)malloc(sizeof(skiplistnode *) * list->max_levels)) == NULL) {
-		return SKIPLIST_ERROR_MEMORY;
-		}
-	for(x = 0; x < list->max_levels; x++)
-		update[x] = NULL;
-
-	/* check to make sure we don't have duplicates */
-	/* NOTE: this could made be more efficient */
-	if(list->allow_duplicates == FALSE) {
-		if(skiplist_find_first(list, data, NULL))
-			return SKIPLIST_ERROR_DUPLICATE;
-		}
-
-	/* find proper position for insert, remember pointers  with an update vector */
-	thisnode = list->head;
-	for(level = list->current_level; level >= 0; level--) {
-
-		while((nextnode = thisnode->forward[level])) {
-			if(list->append_duplicates == TRUE) {
-				if(list->compare_function(nextnode->data, data) > 0)
-					break;
-				}
-			else {
-				if(list->compare_function(nextnode->data, data) >= 0)
-					break;
-				}
-			thisnode = nextnode;
-			}
-
-		update[level] = thisnode;
-		}
-
-	/* get a random level the new node should be inserted at */
-	level = skiplist_random_level(list);
-	/*printf("INSERTION LEVEL: %d\n",level);*/
-
-	/* we're adding a new level... */
-	if(level > list->current_level) {
-		/*printf("NEW LEVEL!\n");*/
-		list->current_level++;
-		level = list->current_level;
-		update[level] = list->head;
-		}
-
-	/* create a new node */
-	if((newnode = skiplist_new_node(list, level)) == NULL) {
-		/*printf("NODE ERROR\n");*/
-		free(update);
-		return SKIPLIST_ERROR_MEMORY;
-		}
-	newnode->data = data;
-
-	/* update pointers to insert node at proper location */
-	do {
-		thisnode = update[level];
-		newnode->forward[level] = thisnode->forward[level];
-		thisnode->forward[level] = newnode;
-
-		}
-	while(--level >= 0);
-
-	/* update counters */
-	list->items++;
-
-	/* free memory */
-	free(update);
-
-	return SKIPLIST_OK;
-	}
-
-
-
-skiplistnode *skiplist_new_node(skiplist *list, int node_levels) {
-	skiplistnode *newnode = NULL;
-	register int x = 0;
-
-	if(list == NULL)
-		return NULL;
-
-	if(node_levels < 0 || node_levels > list->max_levels)
-		return NULL;
-
-	/* allocate memory for node + variable number of level pointers */
-	if((newnode = (skiplistnode *)malloc(sizeof(skiplistnode) + (node_levels * sizeof(skiplistnode *))))) {
-
-		/* initialize forward pointers */
-		for(x = 0; x < node_levels; x++)
-			newnode->forward[x] = NULL;
-
-		/* initialize data pointer */
-		newnode->data = NULL;
-		}
-
-	return newnode;
-	}
-
-
-int skiplist_random_level(skiplist *list) {
-	int level = 0;
-	float r = 0.0;
-
-	if(list == NULL)
-		return -1;
-
-	for(level = 0; level < list->max_levels; level++) {
-		r = ((float)rand() / (float)RAND_MAX);
-		if(r > list->level_probability)
-			break;
-		}
-
-	return (level >= list->max_levels) ? list->max_levels - 1 : level;
-	}
-
-
-int skiplist_empty(skiplist *list) {
-	skiplistnode *this = NULL;
-	skiplistnode *next = NULL;
-	int level = 0;
-
-	if(list == NULL)
-		return ERROR;
-
-	/* free all list nodes (but not header) */
-	for(this = list->head->forward[0]; this != NULL; this = next) {
-		next = this->forward[0];
-		free(this);
-		}
-
-	/* reset level pointers */
-	for(level = list->current_level; level >= 0; level--)
-		list->head->forward[level] = NULL;
-
-	/* reset list level */
-	list->current_level = 0;
-
-	/* reset items */
-	list->items = 0;
-
-	return OK;
-	}
-
-
-
-int skiplist_free(skiplist **list) {
-	skiplistnode *this = NULL;
-	skiplistnode *next = NULL;
-
-	if(list == NULL)
-		return ERROR;
-	if(*list == NULL)
-		return OK;
-
-	/* free header and all list nodes */
-	for(this = (*list)->head; this != NULL; this = next) {
-		next = this->forward[0];
-		free(this);
-		}
-
-	/* free list structure */
-	free(*list);
-	*list = NULL;
-
-	return OK;
-	}
-
-
-
-/* get first item in list */
-void *skiplist_peek(skiplist *list) {
-
-	if(list == NULL)
-		return NULL;
-
-	/* return first item */
-	return list->head->forward[0]->data;
-	}
-
-
-
-/* get/remove first item in list */
-void *skiplist_pop(skiplist *list) {
-	skiplistnode *thisnode = NULL;
-	void *data = NULL;
-	int level = 0;
-
-	if(list == NULL)
-		return NULL;
-
-	/* get first item */
-	thisnode = list->head->forward[0];
-	if(thisnode == NULL)
-		return NULL;
-
-	/* get data for first item */
-	data = thisnode->data;
-
-	/* remove first item from queue - update forward links from head to first node */
-	for(level = 0; level <= list->current_level; level++) {
-		if(list->head->forward[level] == thisnode)
-			list->head->forward[level] = thisnode->forward[level];
-		}
-
-	/* free deleted node */
-	free(thisnode);
-
-	/* adjust items */
-	list->items--;
-
-	return data;
-	}
-
-
-
-/* get first item in list */
-void *skiplist_get_first(skiplist *list, void **node_ptr) {
-	skiplistnode *thisnode = NULL;
-
-	if(list == NULL)
-		return NULL;
-
-	/* get first node */
-	thisnode = list->head->forward[0];
-
-	/* return pointer to node */
-	if(node_ptr)
-		*node_ptr = (void *)thisnode;
-
-	if(thisnode)
-		return thisnode->data;
-	else
-		return NULL;
-	}
-
-
-
-/* get next item in list */
-void *skiplist_get_next(void **node_ptr) {
-	skiplistnode *thisnode = NULL;
-	skiplistnode *nextnode = NULL;
-
-	if(node_ptr == NULL || *node_ptr == NULL)
-		return NULL;
-
-	thisnode = (skiplistnode *)(*node_ptr);
-	nextnode = thisnode->forward[0];
-
-	*node_ptr = (void *)nextnode;
-
-	if(nextnode)
-		return nextnode->data;
-	else
-		return NULL;
-	}
-
-
-
-/* first first item in list */
-void *skiplist_find_first(skiplist *list, void *data, void **node_ptr) {
-	skiplistnode *thisnode = NULL;
-	skiplistnode *nextnode = NULL;
-	int level = 0;
-
-	if(list == NULL || data == NULL)
-		return NULL;
-
-	thisnode = list->head;
-	for(level = list->current_level; level >= 0; level--) {
-		while((nextnode = thisnode->forward[level])) {
-			if(list->compare_function(nextnode->data, data) >= 0)
-				break;
-			thisnode = nextnode;
-			}
-		}
-
-	/* we found it! */
-	if(nextnode && list->compare_function(nextnode->data, data) == 0) {
-		if(node_ptr)
-			*node_ptr = (void *)nextnode;
-		return nextnode->data;
-		}
-	else {
-		if(node_ptr)
-			*node_ptr = NULL;
-		}
-
-	return NULL;
-	}
-
-
-
-/* find next match */
-void *skiplist_find_next(skiplist *list, void *data, void **node_ptr) {
-	skiplistnode *thisnode = NULL;
-	skiplistnode *nextnode = NULL;
-
-	if(list == NULL || data == NULL || node_ptr == NULL)
-		return NULL;
-	if(*node_ptr == NULL)
-		return NULL;
-
-	thisnode = (skiplistnode *)(*node_ptr);
-	nextnode = thisnode->forward[0];
-
-	if(nextnode) {
-		if(list->compare_function(nextnode->data, data) == 0) {
-			*node_ptr = (void *)nextnode;
-			return nextnode->data;
-			}
-		}
-
-	*node_ptr = NULL;
-	return NULL;
-	}
-
-
-
-/* delete (all) matching item(s) from list */
-int skiplist_delete(skiplist *list, void *data) {
-
-	return skiplist_delete_all(list, data);
-	}
-
-
-
-/* delete first matching item from list */
-int skiplist_delete_first(skiplist *list, void *data) {
-	skiplistnode **update = NULL;
-	skiplistnode *thisnode = NULL;
-	skiplistnode *nextnode = NULL;
-	int level = 0;
-	int top_level = 0;
-	int deleted = FALSE;
-	int x = 0;
-
-	if(list == NULL || data == NULL)
-		return ERROR;
-
-	/* initialize update vector */
-	if((update = (skiplistnode **)malloc(sizeof(skiplistnode *) * list->max_levels)) == NULL)
-		return ERROR;
-	for(x = 0; x < list->max_levels; x++)
-		update[x] = NULL;
-
-	/* find location in list */
-	thisnode = list->head;
-	for(top_level = level = list->current_level; level >= 0; level--) {
-		while((nextnode = thisnode->forward[level])) {
-			if(list->compare_function(nextnode->data, data) >= 0)
-				break;
-			thisnode = nextnode;
-			}
-		update[level] = thisnode;
-		}
-
-	/* we found a match! */
-	if(list->compare_function(nextnode->data, data) == 0) {
-
-		/* adjust level pointers to bypass (soon to be) removed node */
-		for(level = 0; level <= top_level; level++) {
-
-			thisnode = update[level];
-			if(thisnode->forward[level] != nextnode)
-				break;
-
-			thisnode->forward[level] = nextnode->forward[level];
-			}
-
-		/* free node memory */
-		free(nextnode);
-
-		/* adjust top/current level of list is necessary */
-		while(list->head->forward[top_level] == NULL && top_level > 0)
-			top_level--;
-		list->current_level = top_level;
-
-		/* adjust items */
-		list->items--;
-
-		deleted = TRUE;
-		}
-
-	/* free memory */
-	free(update);
-
-	return deleted;
-	}
-
-
-
-/* delete all matching items from list */
-int skiplist_delete_all(skiplist *list, void *data) {
-	int deleted = 0;
-	int total_deleted = 0;
-
-	/* NOTE: there is a more efficient way to do this... */
-	while((deleted = skiplist_delete_first(list, data)) == 1)
-		total_deleted++;
-
-	return total_deleted;
-	}
-
-
-
-/* delete specific node from list */
-int skiplist_delete_node(skiplist *list, void *node_ptr) {
-	void *data = NULL;
-	skiplistnode **update = NULL;
-	skiplistnode *thenode = NULL;
-	skiplistnode *thisnode = NULL;
-	skiplistnode *nextnode = NULL;
-	int level = 0;
-	int top_level = 0;
-	int deleted = FALSE;
-	int x = 0;
-
-	if(list == NULL || node_ptr == NULL)
-		return ERROR;
-
-	/* we'll need the data from the node to first find the node */
-	thenode = (skiplistnode *)node_ptr;
-	data = thenode->data;
-
-	/* initialize update vector */
-	if((update = (skiplistnode **)malloc(sizeof(skiplistnode *) * list->max_levels)) == NULL)
-		return ERROR;
-	for(x = 0; x < list->max_levels; x++)
-		update[x] = NULL;
-
-	/* find location in list */
-	thisnode = list->head;
-	for(top_level = level = list->current_level; level >= 0; level--) {
-		while((nextnode = thisnode->forward[level])) {
-
-			/* next node would be too far */
-			if(list->compare_function(nextnode->data, data) > 0)
-				break;
-			/* this is the exact node we want */
-			if(list->compare_function(nextnode->data, data) == 0 && nextnode == thenode)
-				break;
-
-			thisnode = nextnode;
-			}
-		update[level] = thisnode;
-		}
-
-	/* we found a match! (value + pointers match) */
-	if(nextnode && list->compare_function(nextnode->data, data) == 0 && nextnode == thenode) {
-
-		/* adjust level pointers to bypass (soon to be) removed node */
-		for(level = 0; level <= top_level; level++) {
-
-			thisnode = update[level];
-			if(thisnode->forward[level] != nextnode)
-				break;
-
-			thisnode->forward[level] = nextnode->forward[level];
-			}
-
-		/* free node memory */
-		free(nextnode);
-
-		/* adjust top/current level of list is necessary */
-		while(list->head->forward[top_level] == NULL && top_level > 0)
-			top_level--;
-		list->current_level = top_level;
-
-		/* adjust items */
-		list->items--;
-
-		deleted = TRUE;
-		}
-
-	/* free memory */
-	free(update);
-
-	return deleted;
-	}
-
-
-

Modified: nagioscore/trunk/include/common.h
===================================================================
--- nagioscore/trunk/include/common.h	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/include/common.h	2012-08-20 16:26:22 UTC (rev 2079)
@@ -392,24 +392,6 @@
 #define MAX_CHECK_STATS_TYPES                11
 
 
-/************************* GENERAL DEFINITIONS  **************************/
-
-#define	OK				0
-#define ERROR				-2	/* value was changed from -1 so as to not interfere with STATUS_UNKNOWN plugin result */
-
-
-#ifndef TRUE
-#define TRUE				1
-#elif (TRUE!=1)
-#define TRUE				1
-#endif
-#ifndef FALSE
-#define FALSE				0
-#elif (FALSE!=0)
-#define FALSE				0
-#endif
-
-
 /****************** HOST CONFIG FILE READING OPTIONS ********************/
 
 #define READ_HOSTS			1

Deleted: nagioscore/trunk/include/skiplist.h
===================================================================
--- nagioscore/trunk/include/skiplist.h	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/include/skiplist.h	2012-08-20 16:26:22 UTC (rev 2079)
@@ -1,68 +0,0 @@
-/************************************************************************
- *
- * SKIPLIST.H - Skiplist data structures and functions
- *
- *
- * License:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ************************************************************************/
-
-#ifndef _SKIPLIST_H
-#define _SKIPLIST_H
-#include "common.h"
-
-#define SKIPLIST_OK              0
-#define SKIPLIST_ERROR_ARGS      1
-#define SKIPLIST_ERROR_MEMORY    2
-#define SKIPLIST_ERROR_DUPLICATE 3
-
-NAGIOS_BEGIN_DECL
-
-typedef struct skiplistnode_struct {
-	void *data;
-	struct skiplistnode_struct *forward[1]; /* this must be the last element of the struct, as we allocate # of elements during runtime*/
-	} skiplistnode;
-
-typedef struct skiplist_struct {
-	int current_level;
-	int max_levels;
-	float level_probability;
-	unsigned long items;
-	int allow_duplicates;
-	int append_duplicates;
-	int (*compare_function)(void *, void *);
-	skiplistnode *head;
-	} skiplist;
-
-
-skiplist *skiplist_new(int max_levels, float level_probability, int allow_duplicates, int append_duplicates, int (*compare_function)(void *, void *));
-skiplistnode *skiplist_new_node(skiplist *list, int node_levels);
-int skiplist_insert(skiplist *list, void *data);
-int skiplist_random_level(skiplist *list);
-int skiplist_empty(skiplist *list);
-int skiplist_free(skiplist **list);
-void *skiplist_peek(skiplist *);
-void *skiplist_pop(skiplist *);
-void *skiplist_get_first(skiplist *list, void **node_ptr);
-void *skiplist_get_next(void **node_ptr);
-void *skiplist_find_first(skiplist *list, void *data, void **node_ptr);
-void *skiplist_find_next(skiplist *list, void *data, void **node_ptr);
-int skiplist_delete(skiplist *list, void *data);
-int skiplist_delete_first(skiplist *list, void *data);
-int skiplist_delete_all(skiplist *list, void *data);
-int skiplist_delete_node(skiplist *list, void *node_ptr);
-
-NAGIOS_END_DECL
-#endif

Modified: nagioscore/trunk/lib/Makefile.in
===================================================================
--- nagioscore/trunk/lib/Makefile.in	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/lib/Makefile.in	2012-08-20 16:26:22 UTC (rev 2079)
@@ -9,7 +9,7 @@
 
 SNPRINTF_O=@SNPRINTF_O@
 TESTED_SRC_C := squeue.c kvvec.c iocache.c iobroker.c
-SRC_C := $(TESTED_SRC_C) pqueue.c runcmd.c worker.c
+SRC_C := $(TESTED_SRC_C) pqueue.c runcmd.c worker.c skiplist.c
 SRC_O := $(patsubst %.c,%.o,$(SRC_C)) $(SNPRINTF_O)
 TESTS := $(patsubst %.c,test-%,$(TESTED_SRC_C))
 

Modified: nagioscore/trunk/lib/libnagios.h
===================================================================
--- nagioscore/trunk/lib/libnagios.h	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/lib/libnagios.h	2012-08-20 16:26:22 UTC (rev 2079)
@@ -14,4 +14,5 @@
 #include "iocache.h"
 #include "runcmd.h"
 #include "worker.h"
+#include "skiplist.h"
 #endif /* LIB_libnagios_h__ */

Modified: nagioscore/trunk/lib/lnag-utils.h
===================================================================
--- nagioscore/trunk/lib/lnag-utils.h	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/lib/lnag-utils.h	2012-08-20 16:26:22 UTC (rev 2079)
@@ -16,6 +16,22 @@
  * @{
  */
 
+/*
+ * These macros are widely used throughout Nagios
+ */
+#define	OK       0   /**< Indicates successful function call in Nagios */
+#define ERROR   -2   /**< Non-successful function call in Nagios */
+
+#ifdef FALSE
+#undef FALSE
+#endif
+#define FALSE 0 /**< Not true */
+
+#ifdef TRUE
+#undef TRUE
+#endif
+#define TRUE (!FALSE) /** Not false */
+
 /** Useful macro to safely avoid double-free memory corruption */
 #define my_free(ptr) do { if(ptr) { free(ptr); ptr = NULL; } } while(0)
 

Copied: nagioscore/trunk/lib/skiplist.c (from rev 2078, nagioscore/trunk/common/skiplist.c)
===================================================================
--- nagioscore/trunk/lib/skiplist.c	                        (rev 0)
+++ nagioscore/trunk/lib/skiplist.c	2012-08-20 16:26:22 UTC (rev 2079)
@@ -0,0 +1,553 @@
+/************************************************************************
+ *
+ * SKIPLIST.C - Skiplist functions for use in Nagios event/object lists
+ *
+ *
+ * Notes:
+ *
+ * These function implement a slightly modified skiplist from that
+ * described by William Pugh (ftp://ftp.cs.umd.edu/pub/skipLists/skiplists.pdf).
+ * The structures and function were modified to allow the list to act
+ * like a priority queue for the Nagios event list/queue(s).  Multiple nodes with
+ * the same key value are allowed on the list to accomodate multiple events
+ * occurring at the same (second) point in time.  Implemented peek() and pop()
+ * functions to allow for quick event queue processing, and a method to delete
+ * a specific list item, based on its pointer, rather than its data value.  Again,
+ * this is useful for the Nagios event queue.
+ *
+ * License:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include "skiplist.h"
+
+
+static skiplistnode *skiplist_new_node(skiplist *list, int node_levels) {
+	skiplistnode *newnode = NULL;
+	register int x = 0;
+
+	if(list == NULL)
+		return NULL;
+
+	if(node_levels < 0 || node_levels > list->max_levels)
+		return NULL;
+
+	/* allocate memory for node + variable number of level pointers */
+	if((newnode = (skiplistnode *)malloc(sizeof(skiplistnode) + (node_levels * sizeof(skiplistnode *))))) {
+
+		/* initialize forward pointers */
+		for(x = 0; x < node_levels; x++)
+			newnode->forward[x] = NULL;
+
+		/* initialize data pointer */
+		newnode->data = NULL;
+		}
+
+	return newnode;
+	}
+
+
+skiplist *skiplist_new(int max_levels, float level_probability, int allow_duplicates, int append_duplicates, int (*compare_function)(void *, void *)) {
+	skiplist *newlist = NULL;
+
+	/* alloc memory for new list structure */
+	if((newlist = (skiplist *)malloc(sizeof(skiplist)))) {
+
+		/* initialize levels, etc. */
+		newlist->current_level = 0;
+		newlist->max_levels = max_levels;
+		newlist->level_probability = level_probability;
+		newlist->allow_duplicates = allow_duplicates;
+		newlist->append_duplicates = append_duplicates;
+		newlist->items = 0;
+		newlist->compare_function = compare_function;
+
+		/* initialize head node */
+		newlist->head = skiplist_new_node(newlist, max_levels);
+		}
+
+	return newlist;
+	}
+
+
+static int skiplist_random_level(skiplist *list) {
+	int level = 0;
+	float r = 0.0;
+
+	if(list == NULL)
+		return -1;
+
+	for(level = 0; level < list->max_levels; level++) {
+		r = ((float)rand() / (float)RAND_MAX);
+		if(r > list->level_probability)
+			break;
+		}
+
+	return (level >= list->max_levels) ? list->max_levels - 1 : level;
+	}
+
+
+int skiplist_insert(skiplist *list, void *data) {
+	skiplistnode **update = NULL;
+	skiplistnode *thisnode = NULL;
+	skiplistnode *nextnode = NULL;
+	skiplistnode *newnode = NULL;
+	int level = 0;
+	int x = 0;
+
+	if(list == NULL || data == NULL) {
+		return SKIPLIST_ERROR_ARGS;
+		}
+
+	/* initialize update vector */
+	if((update = (skiplistnode **)malloc(sizeof(skiplistnode *) * list->max_levels)) == NULL) {
+		return SKIPLIST_ERROR_MEMORY;
+		}
+	for(x = 0; x < list->max_levels; x++)
+		update[x] = NULL;
+
+	/* check to make sure we don't have duplicates */
+	/* NOTE: this could made be more efficient */
+	if(list->allow_duplicates == FALSE) {
+		if(skiplist_find_first(list, data, NULL))
+			return SKIPLIST_ERROR_DUPLICATE;
+		}
+
+	/* find proper position for insert, remember pointers  with an update vector */
+	thisnode = list->head;
+	for(level = list->current_level; level >= 0; level--) {
+
+		while((nextnode = thisnode->forward[level])) {
+			if(list->append_duplicates == TRUE) {
+				if(list->compare_function(nextnode->data, data) > 0)
+					break;
+				}
+			else {
+				if(list->compare_function(nextnode->data, data) >= 0)
+					break;
+				}
+			thisnode = nextnode;
+			}
+
+		update[level] = thisnode;
+		}
+
+	/* get a random level the new node should be inserted at */
+	level = skiplist_random_level(list);
+
+	/* we're adding a new level... */
+	if(level > list->current_level) {
+		/*printf("NEW LEVEL!\n");*/
+		list->current_level++;
+		level = list->current_level;
+		update[level] = list->head;
+		}
+
+	/* create a new node */
+	if((newnode = skiplist_new_node(list, level)) == NULL) {
+		/*printf("NODE ERROR\n");*/
+		free(update);
+		return SKIPLIST_ERROR_MEMORY;
+		}
+	newnode->data = data;
+
+	/* update pointers to insert node at proper location */
+	do {
+		thisnode = update[level];
+		newnode->forward[level] = thisnode->forward[level];
+		thisnode->forward[level] = newnode;
+
+		}
+	while(--level >= 0);
+
+	/* update counters */
+	list->items++;
+
+	/* free memory */
+	free(update);
+
+	return SKIPLIST_OK;
+	}
+
+
+
+int skiplist_empty(skiplist *list) {
+	skiplistnode *this = NULL;
+	skiplistnode *next = NULL;
+	int level = 0;
+
+	if(list == NULL)
+		return ERROR;
+
+	/* free all list nodes (but not header) */
+	for(this = list->head->forward[0]; this != NULL; this = next) {
+		next = this->forward[0];
+		free(this);
+		}
+
+	/* reset level pointers */
+	for(level = list->current_level; level >= 0; level--)
+		list->head->forward[level] = NULL;
+
+	/* reset list level */
+	list->current_level = 0;
+
+	/* reset items */
+	list->items = 0;
+
+	return OK;
+	}
+
+
+
+int skiplist_free(skiplist **list) {
+	skiplistnode *this = NULL;
+	skiplistnode *next = NULL;
+
+	if(list == NULL)
+		return ERROR;
+	if(*list == NULL)
+		return OK;
+
+	/* free header and all list nodes */
+	for(this = (*list)->head; this != NULL; this = next) {
+		next = this->forward[0];
+		free(this);
+		}
+
+	/* free list structure */
+	free(*list);
+	*list = NULL;
+
+	return OK;
+	}
+
+
+
+/* get first item in list */
+void *skiplist_peek(skiplist *list) {
+
+	if(list == NULL)
+		return NULL;
+
+	/* return first item */
+	return list->head->forward[0]->data;
+	}
+
+
+
+/* get/remove first item in list */
+void *skiplist_pop(skiplist *list) {
+	skiplistnode *thisnode = NULL;
+	void *data = NULL;
+	int level = 0;
+
+	if(list == NULL)
+		return NULL;
+
+	/* get first item */
+	thisnode = list->head->forward[0];
+	if(thisnode == NULL)
+		return NULL;
+
+	/* get data for first item */
+	data = thisnode->data;
+
+	/* remove first item from queue - update forward links from head to first node */
+	for(level = 0; level <= list->current_level; level++) {
+		if(list->head->forward[level] == thisnode)
+			list->head->forward[level] = thisnode->forward[level];
+		}
+
+	/* free deleted node */
+	free(thisnode);
+
+	/* adjust items */
+	list->items--;
+
+	return data;
+	}
+
+
+
+/* get first item in list */
+void *skiplist_get_first(skiplist *list, void **node_ptr) {
+	skiplistnode *thisnode = NULL;
+
+	if(list == NULL)
+		return NULL;
+
+	/* get first node */
+	thisnode = list->head->forward[0];
+
+	/* return pointer to node */
+	if(node_ptr)
+		*node_ptr = (void *)thisnode;
+
+	if(thisnode)
+		return thisnode->data;
+	else
+		return NULL;
+	}
+
+
+
+/* get next item in list */
+void *skiplist_get_next(void **node_ptr) {
+	skiplistnode *thisnode = NULL;
+	skiplistnode *nextnode = NULL;
+
+	if(node_ptr == NULL || *node_ptr == NULL)
+		return NULL;
+
+	thisnode = (skiplistnode *)(*node_ptr);
+	nextnode = thisnode->forward[0];
+
+	*node_ptr = (void *)nextnode;
+
+	if(nextnode)
+		return nextnode->data;
+	else
+		return NULL;
+	}
+
+
+
+/* first first item in list */
+void *skiplist_find_first(skiplist *list, void *data, void **node_ptr) {
+	skiplistnode *thisnode = NULL;
+	skiplistnode *nextnode = NULL;
+	int level = 0;
+
+	if(list == NULL || data == NULL)
+		return NULL;
+
+	thisnode = list->head;
+	for(level = list->current_level; level >= 0; level--) {
+		while((nextnode = thisnode->forward[level])) {
+			if(list->compare_function(nextnode->data, data) >= 0)
+				break;
+			thisnode = nextnode;
+			}
+		}
+
+	/* we found it! */
+	if(nextnode && list->compare_function(nextnode->data, data) == 0) {
+		if(node_ptr)
+			*node_ptr = (void *)nextnode;
+		return nextnode->data;
+		}
+	else {
+		if(node_ptr)
+			*node_ptr = NULL;
+		}
+
+	return NULL;
+	}
+
+
+
+/* find next match */
+void *skiplist_find_next(skiplist *list, void *data, void **node_ptr) {
+	skiplistnode *thisnode = NULL;
+	skiplistnode *nextnode = NULL;
+
+	if(list == NULL || data == NULL || node_ptr == NULL)
+		return NULL;
+	if(*node_ptr == NULL)
+		return NULL;
+
+	thisnode = (skiplistnode *)(*node_ptr);
+	nextnode = thisnode->forward[0];
+
+	if(nextnode) {
+		if(list->compare_function(nextnode->data, data) == 0) {
+			*node_ptr = (void *)nextnode;
+			return nextnode->data;
+			}
+		}
+
+	*node_ptr = NULL;
+	return NULL;
+	}
+
+
+
+/* delete (all) matching item(s) from list */
+int skiplist_delete(skiplist *list, void *data) {
+
+	return skiplist_delete_all(list, data);
+	}
+
+
+
+/* delete first matching item from list */
+int skiplist_delete_first(skiplist *list, void *data) {
+	skiplistnode **update = NULL;
+	skiplistnode *thisnode = NULL;
+	skiplistnode *nextnode = NULL;
+	int level = 0;
+	int top_level = 0;
+	int deleted = FALSE;
+	int x = 0;
+
+	if(list == NULL || data == NULL)
+		return ERROR;
+
+	/* initialize update vector */
+	if((update = (skiplistnode **)malloc(sizeof(skiplistnode *) * list->max_levels)) == NULL)
+		return ERROR;
+	for(x = 0; x < list->max_levels; x++)
+		update[x] = NULL;
+
+	/* find location in list */
+	thisnode = list->head;
+	for(top_level = level = list->current_level; level >= 0; level--) {
+		while((nextnode = thisnode->forward[level])) {
+			if(list->compare_function(nextnode->data, data) >= 0)
+				break;
+			thisnode = nextnode;
+			}
+		update[level] = thisnode;
+		}
+
+	/* we found a match! */
+	if(list->compare_function(nextnode->data, data) == 0) {
+
+		/* adjust level pointers to bypass (soon to be) removed node */
+		for(level = 0; level <= top_level; level++) {
+
+			thisnode = update[level];
+			if(thisnode->forward[level] != nextnode)
+				break;
+
+			thisnode->forward[level] = nextnode->forward[level];
+			}
+
+		/* free node memory */
+		free(nextnode);
+
+		/* adjust top/current level of list is necessary */
+		while(list->head->forward[top_level] == NULL && top_level > 0)
+			top_level--;
+		list->current_level = top_level;
+
+		/* adjust items */
+		list->items--;
+
+		deleted = TRUE;
+		}
+
+	/* free memory */
+	free(update);
+
+	return deleted;
+	}
+
+
+
+/* delete all matching items from list */
+int skiplist_delete_all(skiplist *list, void *data) {
+	int deleted = 0;
+	int total_deleted = 0;
+
+	/* NOTE: there is a more efficient way to do this... */
+	while((deleted = skiplist_delete_first(list, data)) == 1)
+		total_deleted++;
+
+	return total_deleted;
+	}
+
+
+
+/* delete specific node from list */
+int skiplist_delete_node(skiplist *list, void *node_ptr) {
+	void *data = NULL;
+	skiplistnode **update = NULL;
+	skiplistnode *thenode = NULL;
+	skiplistnode *thisnode = NULL;
+	skiplistnode *nextnode = NULL;
+	int level = 0;
+	int top_level = 0;
+	int deleted = FALSE;
+	int x = 0;
+
+	if(list == NULL || node_ptr == NULL)
+		return ERROR;
+
+	/* we'll need the data from the node to first find the node */
+	thenode = (skiplistnode *)node_ptr;
+	data = thenode->data;
+
+	/* initialize update vector */
+	if((update = (skiplistnode **)malloc(sizeof(skiplistnode *) * list->max_levels)) == NULL)
+		return ERROR;
+	for(x = 0; x < list->max_levels; x++)
+		update[x] = NULL;
+
+	/* find location in list */
+	thisnode = list->head;
+	for(top_level = level = list->current_level; level >= 0; level--) {
+		while((nextnode = thisnode->forward[level])) {
+
+			/* next node would be too far */
+			if(list->compare_function(nextnode->data, data) > 0)
+				break;
+			/* this is the exact node we want */
+			if(list->compare_function(nextnode->data, data) == 0 && nextnode == thenode)
+				break;
+
+			thisnode = nextnode;
+			}
+		update[level] = thisnode;
+		}
+
+	/* we found a match! (value + pointers match) */
+	if(nextnode && list->compare_function(nextnode->data, data) == 0 && nextnode == thenode) {
+
+		/* adjust level pointers to bypass (soon to be) removed node */
+		for(level = 0; level <= top_level; level++) {
+
+			thisnode = update[level];
+			if(thisnode->forward[level] != nextnode)
+				break;
+
+			thisnode->forward[level] = nextnode->forward[level];
+			}
+
+		/* free node memory */
+		free(nextnode);
+
+		/* adjust top/current level of list is necessary */
+		while(list->head->forward[top_level] == NULL && top_level > 0)
+			top_level--;
+		list->current_level = top_level;
+
+		/* adjust items */
+		list->items--;
+
+		deleted = TRUE;
+		}
+
+	/* free memory */
+	free(update);
+
+	return deleted;
+	}
+
+
+

Copied: nagioscore/trunk/lib/skiplist.h (from rev 2078, nagioscore/trunk/include/skiplist.h)
===================================================================
--- nagioscore/trunk/lib/skiplist.h	                        (rev 0)
+++ nagioscore/trunk/lib/skiplist.h	2012-08-20 16:26:22 UTC (rev 2079)
@@ -0,0 +1,66 @@
+/************************************************************************
+ *
+ * SKIPLIST.H - Skiplist data structures and functions
+ *
+ *
+ * License:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************/
+
+#ifndef _SKIPLIST_H
+#define _SKIPLIST_H
+#include "lnag-utils.h"
+
+#define SKIPLIST_OK              0 /**< A ok */
+#define SKIPLIST_ERROR_ARGS      1 /**< Bad arguments */
+#define SKIPLIST_ERROR_MEMORY    2 /**< Memory error */
+#define SKIPLIST_ERROR_DUPLICATE 3 /**< Trying to insert non-unique item */
+
+NAGIOS_BEGIN_DECL
+
+typedef struct skiplistnode_struct {
+	void *data;
+	struct skiplistnode_struct *forward[1]; /* this must be the last element of the struct, as we allocate # of elements during runtime*/
+	} skiplistnode;
+
+typedef struct skiplist_struct {
+	int current_level;
+	int max_levels;
+	float level_probability;
+	unsigned long items;
+	int allow_duplicates;
+	int append_duplicates;
+	int (*compare_function)(void *, void *);
+	skiplistnode *head;
+	} skiplist;
+
+
+skiplist *skiplist_new(int max_levels, float level_probability, int allow_duplicates, int append_duplicates, int (*compare_function)(void *, void *));
+int skiplist_insert(skiplist *list, void *data);
+int skiplist_empty(skiplist *list);
+int skiplist_free(skiplist **list);
+void *skiplist_peek(skiplist *);
+void *skiplist_pop(skiplist *);
+void *skiplist_get_first(skiplist *list, void **node_ptr);
+void *skiplist_get_next(void **node_ptr);
+void *skiplist_find_first(skiplist *list, void *data, void **node_ptr);
+void *skiplist_find_next(skiplist *list, void *data, void **node_ptr);
+int skiplist_delete(skiplist *list, void *data);
+int skiplist_delete_first(skiplist *list, void *data);
+int skiplist_delete_all(skiplist *list, void *data);
+int skiplist_delete_node(skiplist *list, void *node_ptr);
+
+NAGIOS_END_DECL
+#endif

Modified: nagioscore/trunk/xdata/xodtemplate.c
===================================================================
--- nagioscore/trunk/xdata/xodtemplate.c	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/xdata/xodtemplate.c	2012-08-20 16:26:22 UTC (rev 2079)
@@ -50,7 +50,6 @@
 #include "../include/objects.h"
 #include "../include/locations.h"
 #include "../include/macros.h"
-#include "../include/skiplist.h"
 
 /**** CORE OR CGI SPECIFIC HEADER FILES ****/
 

Modified: nagioscore/trunk/xdata/xsddefault.c
===================================================================
--- nagioscore/trunk/xdata/xsddefault.c	2012-08-20 16:25:36 UTC (rev 2078)
+++ nagioscore/trunk/xdata/xsddefault.c	2012-08-20 16:26:22 UTC (rev 2079)
@@ -30,7 +30,6 @@
 #include "../include/comments.h"
 #include "../include/downtime.h"
 #include "../include/macros.h"
-#include "../include/skiplist.h"
 
 #ifdef NSCORE
 #include "../include/nagios.h"

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.





More information about the Nagios-commits mailing list