/* * Local defines for the skip-list modules * * Copyright 1996 by Gray Watson. * * $Id: skip_loc.h,v 1.2 1998/03/25 01:07:02 gray Exp $ */ /* * Based on the skip list algorithms described in the June 1990 issue * of CACM and invented by William Pugh in 1987. */ #ifndef __SKIP_LOC_H__ #define __SKIP_LOC_H__ /* * for random_level function: */ /* * define the following implement the hack described in the CACM * paper: if a random level is generated that is more than the current * maximum level, the current maximum level plus one is used instead. */ #define CACM_HACK 1 #define INCREASE_LEVEL(rand) (((rand) % 10000) < 5000) #define SKIP_MAGIC 0x10DD1DEA /* NOTE: lev-1 is used because we already have 1 entry in skip_node_t */ #define NODE_SIZE(lev) (sizeof(skip_node_t) + (lev - 1) * \ sizeof(skip_node_t *)) #ifdef NO_MMAP #define SKIP_POINTER(skip_p, type, pnt) pnt #else #define SKIP_POINTER(skip_p, type, pnt) \ (skip_p->sk_mmap == NULL ? pnt : (pnt == NULL ? NULL : \ (type)((char *)pnt + \ (long)skip_p->sk_mmap))) #endif /* * type of entry's key or data. * * NOTE: we should not do the da_data[0] here because datum_t is part of * the node_st below and so we don't save anything. */ typedef struct { unsigned int da_size; /* size of data */ void *da_data; /* pointer to data */ } datum_t; /* * one element in the skip list. this is a dynamically sized node * depending on the number of forward pointers involved. */ struct skip_node_st { datum_t sn_key; /* search key for data */ datum_t sn_data; /* actual data to be stored */ unsigned int sn_forward_n; /* number of forward entries */ struct skip_node_st *sn_forward_p[1]; /* list of forward pointers */ }; typedef struct skip_node_st skip_node_t; typedef skip_node_t skip_node_ext_t; /* * NOTE: since we would need to realloc the head forwardp list, but * don't want the user's pointer to change, we need to have the node_p * pointer to the head node in our tree. * * Also, we could just encorporate a pointer to a forward-list and the * forward_n in this struct but it simplifies the code to make node_p * be a node-pointer. */ typedef struct skip_st { unsigned int sk_magic; /* magic goodie */ unsigned int sk_entry_n; /* number of entries */ skip_compare_t sk_compare; /* compare function */ skip_node_t *sk_top_p; /* pointer to head node */ skip_node_t *sk_this_p; /* linear function */ struct skip_st *sk_mmap; /* mmaped skip list */ long sk_file_size; /* size of on-disk space */ } skip_t; typedef skip_t skip_ext_t; /* * list of power of two numbers to normalize a list */ static int power_two[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, /* NOTE: this is 2^31 - 1 so not exceed signed int */ 2147483647, 0 }; /* * to map error to string */ typedef struct { int es_error; /* error number */ char *es_string; /* assocaited string */ } error_str_t; static error_str_t errors[] = { { SKIP_ERROR_NONE, "no error" }, { SKIP_ERROR_PNT, "invalid skip pointer" }, { SKIP_ERROR_ARG_NULL, "buffer argument is null" }, { SKIP_ERROR_SIZE, "incorrect size argument" }, { SKIP_ERROR_OVERWRITE, "key exists and no overwrite" }, { SKIP_ERROR_NOT_FOUND, "key does not exist" }, { SKIP_ERROR_ALLOC, "error allocating memory" }, { SKIP_ERROR_LINEAR, "linear access not in progress" }, { SKIP_ERROR_FILE, "could not open file" }, { SKIP_ERROR_INTERNAL, "found inconsistancy with list" }, { SKIP_ERROR_MMAP_NONE, "no mmap support compiled in library" }, { SKIP_ERROR_MMAP, "could not mmap the file" }, { SKIP_ERROR_MMAP_OP, "operation not valid on mmap files" }, { 0 } }; #define INVALID_ERROR "invalid error code" /* * mapping of memory pointer to size */ typedef struct { skip_node_t *ps_node_p; /* pointer to a node */ long ps_size; /* its corresponding size */ } pnt_size_t; #endif /* ! __SKIP_LOC_H__ */