blob: 5a3d6da2229b1eb4baa8c5f7271408bd3ce22b37 [file] [log] [blame]
sewardjb4112022007-11-09 22:49:28 +00001
2/*--------------------------------------------------------------------*/
3/*--- An AVL tree based finite map for word keys and word values. ---*/
4/*--- Inspired by Haskell's "FiniteMap" library. ---*/
sewardj896f6f92008-08-19 08:38:52 +00005/*--- pub_tool_wordfm.h ---*/
sewardjb4112022007-11-09 22:49:28 +00006/*--------------------------------------------------------------------*/
7
8/*
sewardj896f6f92008-08-19 08:38:52 +00009 This file is part of Valgrind, a dynamic binary instrumentation
10 framework.
sewardjb4112022007-11-09 22:49:28 +000011
Elliott Hughesed398002017-06-21 14:41:24 -070012 Copyright (C) 2007-2017 Julian Seward
sewardjb4112022007-11-09 22:49:28 +000013 jseward@acm.org
14
15 This code is based on previous work by Nicholas Nethercote
16 (coregrind/m_oset.c) which is
17
Elliott Hughesed398002017-06-21 14:41:24 -070018 Copyright (C) 2005-2017 Nicholas Nethercote
sewardjb4112022007-11-09 22:49:28 +000019 njn@valgrind.org
20
21 which in turn was derived partially from:
22
23 AVL C library
24 Copyright (C) 2000,2002 Daniel Nagy
25
26 This program is free software; you can redistribute it and/or
27 modify it under the terms of the GNU General Public License as
28 published by the Free Software Foundation; either version 2 of
29 the License, or (at your option) any later version.
30 [...]
31
32 (taken from libavl-0.4/debian/copyright)
33
34 This program is free software; you can redistribute it and/or
35 modify it under the terms of the GNU General Public License as
36 published by the Free Software Foundation; either version 2 of the
37 License, or (at your option) any later version.
38
39 This program is distributed in the hope that it will be useful, but
40 WITHOUT ANY WARRANTY; without even the implied warranty of
41 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 General Public License for more details.
43
44 You should have received a copy of the GNU General Public License
45 along with this program; if not, write to the Free Software
46 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
47 02111-1307, USA.
48
49 The GNU General Public License is contained in the file COPYING.
50*/
51
sewardj896f6f92008-08-19 08:38:52 +000052#ifndef __PUB_TOOL_WORDFM_H
53#define __PUB_TOOL_WORDFM_H
sewardjb4112022007-11-09 22:49:28 +000054
florian535fb1b2013-09-15 13:54:34 +000055#include "pub_tool_basics.h" // Word
56
sewardjb4112022007-11-09 22:49:28 +000057//------------------------------------------------------------------//
58//--- WordFM ---//
59//--- Public interface ---//
60//------------------------------------------------------------------//
61
sewardjfc4b63a2008-02-17 11:46:58 +000062/* As of r7409 (15 Feb 08), all these word-based abstractions (WordFM,
63 WordSet, WordBag) now operate on unsigned words (UWord), whereas
64 they previously operated on signed words (Word). This became a
65 problem, when using unboxed comparisons (when kCmp == NULL), with
sewardj896f6f92008-08-19 08:38:52 +000066 the introduction of VG_(initIterAtFM), which allows iteration over
sewardjfc4b63a2008-02-17 11:46:58 +000067 parts of mappings. Iterating over a mapping in increasing order of
68 signed Word keys is not what callers expect when iterating through
69 maps whose keys represent addresses (Addr) since Addr is unsigned,
70 and causes logical problems and assertion failures. */
71
sewardjb4112022007-11-09 22:49:28 +000072typedef struct _WordFM WordFM; /* opaque */
73
sewardj250ec2e2008-02-15 22:02:30 +000074/* Allocate and initialise a WordFM. If kCmp is non-NULL, elements in
75 the set are ordered according to the ordering specified by kCmp,
76 which becomes obvious if you use VG_(initIterFM),
77 VG_(initIterAtFM), VG_(nextIterFM), VG_(doneIterFM) to iterate over
sewardjfc4b63a2008-02-17 11:46:58 +000078 sections of the map, or the whole thing. If kCmp is NULL then the
79 ordering used is unsigned word ordering (UWord) on the key
florian6aa8bd02014-09-14 22:11:44 +000080 values.
81 The function never returns NULL. */
florian54fe2022012-10-27 23:07:42 +000082WordFM* VG_(newFM) ( void* (*alloc_nofail)( const HChar* cc, SizeT ),
83 const HChar* cc,
sewardjb4112022007-11-09 22:49:28 +000084 void (*dealloc)(void*),
sewardj250ec2e2008-02-15 22:02:30 +000085 Word (*kCmp)(UWord,UWord) );
sewardjb4112022007-11-09 22:49:28 +000086
87/* Free up the FM. If kFin is non-NULL, it is applied to keys
88 before the FM is deleted; ditto with vFin for vals. */
sewardj896f6f92008-08-19 08:38:52 +000089void VG_(deleteFM) ( WordFM*, void(*kFin)(UWord), void(*vFin)(UWord) );
sewardjb4112022007-11-09 22:49:28 +000090
91/* Add (k,v) to fm. If a binding for k already exists, it is updated
92 to map to this new v. In that case we should really return the
sewardj9c606bd2008-09-18 18:12:50 +000093 previous v so that caller can finalise it. Oh well. Returns
94 True if a binding for k already exists. */
95Bool VG_(addToFM) ( WordFM* fm, UWord k, UWord v );
sewardjb4112022007-11-09 22:49:28 +000096
97// Delete key from fm, returning associated key and val if found
sewardj896f6f92008-08-19 08:38:52 +000098Bool VG_(delFromFM) ( WordFM* fm,
sewardj250ec2e2008-02-15 22:02:30 +000099 /*OUT*/UWord* oldK, /*OUT*/UWord* oldV, UWord key );
sewardjb4112022007-11-09 22:49:28 +0000100
101// Look up in fm, assigning found key & val at spec'd addresses
florianee0d0e92014-10-18 16:17:13 +0000102Bool VG_(lookupFM) ( const WordFM* fm,
sewardj250ec2e2008-02-15 22:02:30 +0000103 /*OUT*/UWord* keyP, /*OUT*/UWord* valP, UWord key );
sewardjb4112022007-11-09 22:49:28 +0000104
sewardj9c606bd2008-09-18 18:12:50 +0000105// Find the closest key values bracketing the given key, assuming the
106// given key is not present in the map. minKey and maxKey are the
107// minimum and maximum possible key values. The resulting bracket
108// values are returned in *kMinP and *kMaxP. It follows that if fm is
109// empty then the returned values are simply minKey and maxKey.
110//
sewardj95208452008-10-18 19:55:31 +0000111// For convenience the associated value fields are also returned
112// through *vMinP and *vMaxP. To make that possible in the general
113// case, the caller must supply via minVal and maxVal, the value
114// fields associated with minKey and maxKey.
115//
sewardj9c606bd2008-09-18 18:12:50 +0000116// If the operation was successful (that is, the given key is not
117// present), True is returned. If the given key is in fact present,
sewardj95208452008-10-18 19:55:31 +0000118// False is returned, and *kMinP, *vMinP, *kMaxP and *vMaxP are
119// undefined. Any of kMinP, vMinP, kMaxP and vMaxP may be safely
120// supplied as NULL.
florianee0d0e92014-10-18 16:17:13 +0000121Bool VG_(findBoundsFM)( const WordFM* fm,
sewardj95208452008-10-18 19:55:31 +0000122 /*OUT*/UWord* kMinP, /*OUT*/UWord* vMinP,
123 /*OUT*/UWord* kMaxP, /*OUT*/UWord* vMaxP,
124 UWord minKey, UWord minVal,
125 UWord maxKey, UWord maxVal,
126 UWord key );
sewardj9c606bd2008-09-18 18:12:50 +0000127
sewardj0b5f9fc2008-11-13 13:17:06 +0000128// How many elements are there in fm? NOTE: dangerous in the
129// sense that this is not an O(1) operation but rather O(N),
130// since it involves walking the whole tree.
florianee0d0e92014-10-18 16:17:13 +0000131UWord VG_(sizeFM) ( const WordFM* fm );
sewardjb4112022007-11-09 22:49:28 +0000132
133// set up FM for iteration
sewardj896f6f92008-08-19 08:38:52 +0000134void VG_(initIterFM) ( WordFM* fm );
sewardjb4112022007-11-09 22:49:28 +0000135
sewardj250ec2e2008-02-15 22:02:30 +0000136// set up FM for iteration so that the first key subsequently produced
sewardj896f6f92008-08-19 08:38:52 +0000137// by VG_(nextIterFM) is the smallest key in the map >= start_at.
sewardj250ec2e2008-02-15 22:02:30 +0000138// Naturally ">=" is defined by the comparison function supplied to
sewardj896f6f92008-08-19 08:38:52 +0000139// VG_(newFM), as documented above.
140void VG_(initIterAtFM) ( WordFM* fm, UWord start_at );
sewardjae5137e2008-01-17 23:19:54 +0000141
sewardjb4112022007-11-09 22:49:28 +0000142// get next key/val pair. Will assert if fm has been modified
sewardjae5137e2008-01-17 23:19:54 +0000143// or looked up in since initIterFM/initIterWithStartFM was called.
sewardj896f6f92008-08-19 08:38:52 +0000144Bool VG_(nextIterFM) ( WordFM* fm,
sewardj250ec2e2008-02-15 22:02:30 +0000145 /*OUT*/UWord* pKey, /*OUT*/UWord* pVal );
sewardjb4112022007-11-09 22:49:28 +0000146
florian6aa8bd02014-09-14 22:11:44 +0000147// Finish an FM iteration
sewardj896f6f92008-08-19 08:38:52 +0000148void VG_(doneIterFM) ( WordFM* fm );
sewardjb4112022007-11-09 22:49:28 +0000149
150// Deep copy a FM. If dopyK is NULL, keys are copied verbatim.
151// If non-null, dopyK is applied to each key to generate the
florian6aa8bd02014-09-14 22:11:44 +0000152// version in the new copy. dopyK may be called with a NULL argument
153// in which case it should return NULL. For all other argument values
154// dopyK must not return NULL. Ditto with dopyV for values.
155// VG_(dopyFM) never returns NULL.
sewardj896f6f92008-08-19 08:38:52 +0000156WordFM* VG_(dopyFM) ( WordFM* fm,
sewardj250ec2e2008-02-15 22:02:30 +0000157 UWord(*dopyK)(UWord), UWord(*dopyV)(UWord) );
sewardjb4112022007-11-09 22:49:28 +0000158
159//------------------------------------------------------------------//
160//--- end WordFM ---//
161//--- Public interface ---//
162//------------------------------------------------------------------//
163
164//------------------------------------------------------------------//
165//--- WordBag (unboxed words only) ---//
166//--- Public interface ---//
167//------------------------------------------------------------------//
168
169typedef struct _WordBag WordBag; /* opaque */
170
florian6aa8bd02014-09-14 22:11:44 +0000171/* Allocate and initialise a WordBag. Never returns NULL. */
florian54fe2022012-10-27 23:07:42 +0000172WordBag* VG_(newBag) ( void* (*alloc_nofail)( const HChar* cc, SizeT ),
173 const HChar* cc,
sewardjb4112022007-11-09 22:49:28 +0000174 void (*dealloc)(void*) );
175
176/* Free up the Bag. */
sewardj896f6f92008-08-19 08:38:52 +0000177void VG_(deleteBag) ( WordBag* );
sewardjb4112022007-11-09 22:49:28 +0000178
179/* Add a word. */
sewardj896f6f92008-08-19 08:38:52 +0000180void VG_(addToBag)( WordBag*, UWord );
sewardjb4112022007-11-09 22:49:28 +0000181
182/* Find out how many times the given word exists in the bag. */
florianee0d0e92014-10-18 16:17:13 +0000183UWord VG_(elemBag) ( const WordBag*, UWord );
sewardjb4112022007-11-09 22:49:28 +0000184
185/* Delete a word from the bag. */
sewardj896f6f92008-08-19 08:38:52 +0000186Bool VG_(delFromBag)( WordBag*, UWord );
sewardjb4112022007-11-09 22:49:28 +0000187
188/* Is the bag empty? */
florianee0d0e92014-10-18 16:17:13 +0000189Bool VG_(isEmptyBag)( const WordBag* );
sewardjb4112022007-11-09 22:49:28 +0000190
191/* Does the bag have exactly one element? */
florianee0d0e92014-10-18 16:17:13 +0000192Bool VG_(isSingletonTotalBag)( const WordBag* );
sewardjb4112022007-11-09 22:49:28 +0000193
194/* Return an arbitrary element from the bag. */
florianee0d0e92014-10-18 16:17:13 +0000195UWord VG_(anyElementOfBag)( const WordBag* );
sewardjb4112022007-11-09 22:49:28 +0000196
197/* How many different / total elements are in the bag? */
florianee0d0e92014-10-18 16:17:13 +0000198UWord VG_(sizeUniqueBag)( const WordBag* ); /* fast */
199UWord VG_(sizeTotalBag)( const WordBag* ); /* warning: slow */
sewardjb4112022007-11-09 22:49:28 +0000200
201/* Iterating over the elements of a bag. */
sewardj896f6f92008-08-19 08:38:52 +0000202void VG_(initIterBag)( WordBag* );
203Bool VG_(nextIterBag)( WordBag*, /*OUT*/UWord* pVal, /*OUT*/UWord* pCount );
204void VG_(doneIterBag)( WordBag* );
sewardjb4112022007-11-09 22:49:28 +0000205
206//------------------------------------------------------------------//
207//--- end WordBag (unboxed words only) ---//
208//--- Public interface ---//
209//------------------------------------------------------------------//
210
sewardj896f6f92008-08-19 08:38:52 +0000211#endif /* ! __PUB_TOOL_WORDFM_H */
sewardjb4112022007-11-09 22:49:28 +0000212
213/*--------------------------------------------------------------------*/
sewardj896f6f92008-08-19 08:38:52 +0000214/*--- end pub_tool_wordfm.h ---*/
sewardjb4112022007-11-09 22:49:28 +0000215/*--------------------------------------------------------------------*/