blob: cd6682da2312d7589497b2cc7e50f64cfaca0e70 [file] [log] [blame]
/*--------------------------------------------------------------------*/
/*--- 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 ---*/
/*--------------------------------------------------------------------*/