blob: 224f1ff6b92675c7ac2664e0284ead4cd5b9b2ff [file] [log] [blame]
/*
*
* Thread-safe Skiplist Using Integer Identifiers
* Copyright 1998-2000 Scott Shambarger (scott@shambarger.net)
*
* This software is open source. Permission to use, copy, modify, and
* distribute this software for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies. No
* warranty of any kind is expressed or implied. Use at your own risk.
*
* 1/14/2001 blong
* Made it use neo errs... probably need to check locking functions
* for error returns...
*
*/
#ifndef __SKIPLIST_H_
#define __SKIPLIST_H_
#include "util/neo_err.h"
__BEGIN_DECLS
/*
* Larger values of <root> means fewer levels and faster lookups,
* but more variability in those lookup times (range limited from 2 to 4).
*
* <maxLevel> should be calculated from expected list size using (^ = power):
*
* <root> ^ <maxLevel> == expected # of items
*
* I've capped <maxLevel> at 20, which would be good for a minimum of
* 1 million items on lists with <root> == 2.
*
*
* Example
* skipNewList(&(my_wdb->ondisk), 0, 4, 2, 0, NULL, NULL);
*/
#define SKIP_MAXLEVEL 20
/* SKIP LIST TYPEDEFS */
typedef struct skipList_struct *skipList;
typedef void (*skipFreeValue)(void *value, void *ctx);
NEOERR *skipNewList(skipList *skip, int threaded, int root, int maxLevel,
int flushLimit, skipFreeValue freeValue, void *ctx);
/*
* Function: skipNewList - create a skip list.
* Description: Returns a new skip list. If <threaded> is true, list is
* multi-thread safe. <root> and <maxLevel> determine
* performance and expected size (see discussion above).
* <flushLimit> is for threaded lists and determines the
* maximum number of deleted items to keep cached during
* concurrent searches. Once the limit is reached, new
* concurrent reads are blocked until all deleted items are
* flushed.
* Input: threaded - true if list should be thread-safe.
* root - performance parameter (see above).
* maxLevel - performance parameter (see above).
* flushLimit - max deleted items to keep cached before
* forcing a flush.
* freeValue - callback made whenever a value is flushed.
* ctx - context to pass to <freeValue>.
* Output: None.
* Return: New skip list, NULL on error.
* MT-Level: Safe.
*/
void skipFreeList(skipList list);
/*
* Function: skipFreeList - free a skip list.
* Description: Release all resources used by <list> including all key/value
* pairs.
* Input: list - list to free.
* Output: None.
* Return: None.
* MT-Level: Safe for unique <list>.
*/
void *skipNext(skipList list, UINT32 *pkey, void **plock);
/*
* Function: skipNext - find next item.
* Description: Searches in list <list> for item with key next larger
* that the one in <pkey>, and returns its value if
* found, or NULL if not. If <plock> is non-NULL, then
* the lock returned in <plock> will be associated with
* the returned value. Until this lock is passed to
* skipRelease(), the value will not be freed with the
* freeValue callback (see skipNewList()).
* Input: list - list to search in.
* pkey - pointer to previous key (0 to start).
* plock - place for value lock (or NULL).
* Output: pkey - set to new key.
* plock - set to value lock.
* Return: Value associated with new <pkey>, or NULL last item.
* MT-Level: Safe if <list> thread-safe.
*/
void *skipSearch(skipList list, UINT32 key, void **plock);
/*
* Function: skipSearch - search a skip list.
* Description: Searches for <key> in <list>, and returns value if
* found, or NULL if not. If <plock> is non-NULL, then
* the lock returned in <plock> will be associated with
* the returned value. Until this lock is passed to
* skipRelease(), the value will not be freed with the
* freeValue callback (see skipNewList()).
* Input: list - list to search in.
* key - key to look for.
* plock - place for value lock (or NULL).
* Output: plock - set to value lock.
* Return: Value associated with <key>, or NULL if <key> not found.
* MT-Level: Safe if <list> thread-safe.
*/
void skipRelease(skipList list, void *lock);
/*
* Function: skipRelease - release lock on value.
* Description: Releases the lock on the value associated with <lock>. Once
* the lock is released, the freeValue callback can be called
* and the item freed (see skipNewList()).
* Input: list - list containing value to release.
* lock - lock to release.
* Output: None.
* Return: None.
* MT-Level: Safe if <list> thread-safe.
*/
NEOERR *skipInsert(skipList list, UINT32 key, void *value, int allowUpdate);
/*
* Function: skipInsert - insert an item.
* Description: Inserts the <key>/<value> pair into the <list>.
* Key values 0 and -1 are reserved (and illegal).
* If key is already in list, and <allowUpdate> is true,
* value is updated, otherwise SKIPERR_EXISTS is returned.
* Input: list - list to add pair to.
* key - key identifying <value>.
* value - value to store (may NOT be NULL)
* Output: None.
* Return: NERR_ASSERT on invalid key or value
* NERR_DUPLICATE if allowUpdate is 0 and key exists
* NERR_NOMEM
* MT-Level: Safe if <list> thread-safe.
*/
void skipDelete(skipList list, UINT32 key);
/*
* Function: skipDelete - delete an item.
* Description: Delete the item associated with <key> from <list>.
* Input: list - list to delete item from.
* key - key identifying value to delete.
* Output: None.
* Return: None.
* MT-Level: Safe if <list> thread-safe.
*/
__END_DECLS
#endif /* __SKIPLIST_H_ */