| /* |
| * |
| * 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_ */ |
| |
| |
| |
| |
| |
| |