/*--------------------------------------------------------------------*/ /*--- SkipList: a skiplist implementaiton. pub_tool_skiplist.h ---*/ /*--------------------------------------------------------------------*/ /* This file is part of Valgrind, a dynamic binary instrumentation framework. Copyright (C) 2000-2005 Julian Seward jseward@acm.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. The GNU General Public License is contained in the file COPYING. */ #ifndef __PUB_TOOL_SKIPLIST_H #define __PUB_TOOL_SKIPLIST_H /* The idea here is that the skiplist puts its per-element data at the end of the structure. When you initialize the skiplist, you tell it what structure your list elements are going to be. Then you should allocate them with VG_(SkipNode_Alloc), which will allocate enough memory for the extra bits. */ typedef struct _SkipList SkipList; typedef struct _SkipNode SkipNode; typedef Int (*SkipCmp_t)(const void *key1, const void *key2); struct _SkipList { const Short arena; // allocation arena const UShort size; // structure size (excluding SkipNode) const UShort keyoff; // key offset const SkipCmp_t cmp; // compare two keys Char * (*strkey)(void *); // stringify a key (for debugging) SkipNode *head; // list head }; /* Use this macro to initialize your skiplist head: _type is the type of your element structure _key is the field within that type which you want to use as the key _cmp is the comparison function for keys - it gets two typeof(_key) pointers as args _strkey is a function which can return a string of your key - it's only used for debugging _arena is the arena to use for allocation - -1 is the default */ #define VG_SKIPLIST_INIT(_type, _key, _cmp, _strkey, _arena) \ { \ .arena = _arena, \ .size = sizeof(_type), \ .keyoff = offsetof(_type, _key), \ .cmp = _cmp, \ .strkey = _strkey, \ .head = NULL, \ } /* List operations: SkipList_Find_* search a list. The 3 variants are: Before: returns a node which is <= key, or NULL if none Exact: returns a node which is == key, or NULL if none After: returns a node which is >= key, or NULL if none SkipList_Insert inserts a new element into the list. Duplicates are forbidden. The element must have been created with SkipNode_Alloc! SkipList_Remove removes an element from the list and returns it. It doesn't free the memory. */ extern void *VG_(SkipList_Find_Before) (const SkipList *l, void *key); extern void *VG_(SkipList_Find_Exact) (const SkipList *l, void *key); extern void *VG_(SkipList_Find_After) (const SkipList *l, void *key); extern void VG_(SkipList_Insert) ( SkipList *l, void *data); extern void *VG_(SkipList_Remove) ( SkipList *l, void *key); /* Some useful standard comparisons */ extern Int VG_(cmp_Addr) (const void *a, const void *b); extern Int VG_(cmp_Int) (const void *a, const void *b); extern Int VG_(cmp_UInt) (const void *a, const void *b); extern Int VG_(cmp_string)(const void *a, const void *b); /* Node (element) operations: SkipNode_Alloc: allocate memory for a new element on the list. Must be used before an element can be inserted! Returns NULL if not enough memory. SkipNode_Free: free memory allocated above SkipNode_First: return the first element on the list SkipNode_Next: return the next element after "data" on the list - NULL for none You can iterate through a SkipList like this: for (x = VG_(SkipNode_First)(&list); x != NULL; x = VG_(SkipNode_Next)(&list, x)) { ... } */ extern void *VG_(SkipNode_Alloc) (const SkipList *l); extern void VG_(SkipNode_Free) (const SkipList *l, void *p); extern void *VG_(SkipNode_First) (const SkipList *l); extern void *VG_(SkipNode_Next) (const SkipList *l, void *data); #endif // __PUB_TOOL_SKIPLIST_H /*--------------------------------------------------------------------*/ /*--- end ---*/ /*--------------------------------------------------------------------*/