blob: db89712618c20140d957a45e821e085af2e42c39 [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. ---*/
5/*--- hg_wordfm.h ---*/
6/*--------------------------------------------------------------------*/
7
8/*
9 This file is part of Helgrind, a Valgrind tool for detecting errors
10 in threaded programs.
11
sewardj4d474d02008-02-11 11:34:59 +000012 Copyright (C) 2007-2008 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
sewardj4d474d02008-02-11 11:34:59 +000018 Copyright (C) 2005-2008 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
52#ifndef __HG_WORDFM_H
53#define __HG_WORDFM_H
54
55//------------------------------------------------------------------//
56//--- WordFM ---//
57//--- Public interface ---//
58//------------------------------------------------------------------//
59
sewardjfc4b63a2008-02-17 11:46:58 +000060/* As of r7409 (15 Feb 08), all these word-based abstractions (WordFM,
61 WordSet, WordBag) now operate on unsigned words (UWord), whereas
62 they previously operated on signed words (Word). This became a
63 problem, when using unboxed comparisons (when kCmp == NULL), with
64 the introduction of HG_(initIterAtFM), which allows iteration over
65 parts of mappings. Iterating over a mapping in increasing order of
66 signed Word keys is not what callers expect when iterating through
67 maps whose keys represent addresses (Addr) since Addr is unsigned,
68 and causes logical problems and assertion failures. */
69
sewardjb4112022007-11-09 22:49:28 +000070typedef struct _WordFM WordFM; /* opaque */
71
sewardj250ec2e2008-02-15 22:02:30 +000072/* Allocate and initialise a WordFM. If kCmp is non-NULL, elements in
73 the set are ordered according to the ordering specified by kCmp,
74 which becomes obvious if you use VG_(initIterFM),
75 VG_(initIterAtFM), VG_(nextIterFM), VG_(doneIterFM) to iterate over
sewardjfc4b63a2008-02-17 11:46:58 +000076 sections of the map, or the whole thing. If kCmp is NULL then the
77 ordering used is unsigned word ordering (UWord) on the key
78 values. */
sewardjb4112022007-11-09 22:49:28 +000079WordFM* HG_(newFM) ( void* (*alloc_nofail)( SizeT ),
80 void (*dealloc)(void*),
sewardj250ec2e2008-02-15 22:02:30 +000081 Word (*kCmp)(UWord,UWord) );
sewardjb4112022007-11-09 22:49:28 +000082
83/* Free up the FM. If kFin is non-NULL, it is applied to keys
84 before the FM is deleted; ditto with vFin for vals. */
sewardj250ec2e2008-02-15 22:02:30 +000085void HG_(deleteFM) ( WordFM*, void(*kFin)(UWord), void(*vFin)(UWord) );
sewardjb4112022007-11-09 22:49:28 +000086
87/* Add (k,v) to fm. If a binding for k already exists, it is updated
88 to map to this new v. In that case we should really return the
89 previous v so that caller can finalise it. Oh well. */
sewardj250ec2e2008-02-15 22:02:30 +000090void HG_(addToFM) ( WordFM* fm, UWord k, UWord v );
sewardjb4112022007-11-09 22:49:28 +000091
92// Delete key from fm, returning associated key and val if found
93Bool HG_(delFromFM) ( WordFM* fm,
sewardj250ec2e2008-02-15 22:02:30 +000094 /*OUT*/UWord* oldK, /*OUT*/UWord* oldV, UWord key );
sewardjb4112022007-11-09 22:49:28 +000095
96// Look up in fm, assigning found key & val at spec'd addresses
97Bool HG_(lookupFM) ( WordFM* fm,
sewardj250ec2e2008-02-15 22:02:30 +000098 /*OUT*/UWord* keyP, /*OUT*/UWord* valP, UWord key );
sewardjb4112022007-11-09 22:49:28 +000099
100// How many elements are there in fm?
sewardj250ec2e2008-02-15 22:02:30 +0000101UWord HG_(sizeFM) ( WordFM* fm );
sewardjb4112022007-11-09 22:49:28 +0000102
103// set up FM for iteration
104void HG_(initIterFM) ( WordFM* fm );
105
sewardj250ec2e2008-02-15 22:02:30 +0000106// set up FM for iteration so that the first key subsequently produced
107// by HG_(nextIterFM) is the smallest key in the map >= start_at.
108// Naturally ">=" is defined by the comparison function supplied to
109// HG_(newFM), as documented above.
110void HG_(initIterAtFM) ( WordFM* fm, UWord start_at );
sewardjae5137e2008-01-17 23:19:54 +0000111
sewardjb4112022007-11-09 22:49:28 +0000112// get next key/val pair. Will assert if fm has been modified
sewardjae5137e2008-01-17 23:19:54 +0000113// or looked up in since initIterFM/initIterWithStartFM was called.
sewardjb4112022007-11-09 22:49:28 +0000114Bool HG_(nextIterFM) ( WordFM* fm,
sewardj250ec2e2008-02-15 22:02:30 +0000115 /*OUT*/UWord* pKey, /*OUT*/UWord* pVal );
sewardjb4112022007-11-09 22:49:28 +0000116
117// clear the I'm iterating flag
118void HG_(doneIterFM) ( WordFM* fm );
119
120// Deep copy a FM. If dopyK is NULL, keys are copied verbatim.
121// If non-null, dopyK is applied to each key to generate the
122// version in the new copy. In that case, if the argument to dopyK
123// is non-NULL but the result is NULL, it is assumed that dopyK
124// could not allocate memory, in which case the copy is abandoned
125// and NULL is returned. Ditto with dopyV for values.
126WordFM* HG_(dopyFM) ( WordFM* fm,
sewardj250ec2e2008-02-15 22:02:30 +0000127 UWord(*dopyK)(UWord), UWord(*dopyV)(UWord) );
sewardjb4112022007-11-09 22:49:28 +0000128
129//------------------------------------------------------------------//
130//--- end WordFM ---//
131//--- Public interface ---//
132//------------------------------------------------------------------//
133
134//------------------------------------------------------------------//
135//--- WordBag (unboxed words only) ---//
136//--- Public interface ---//
137//------------------------------------------------------------------//
138
139typedef struct _WordBag WordBag; /* opaque */
140
141/* Allocate and initialise a WordBag */
142WordBag* HG_(newBag) ( void* (*alloc_nofail)( SizeT ),
143 void (*dealloc)(void*) );
144
145/* Free up the Bag. */
146void HG_(deleteBag) ( WordBag* );
147
148/* Add a word. */
sewardj250ec2e2008-02-15 22:02:30 +0000149void HG_(addToBag)( WordBag*, UWord );
sewardjb4112022007-11-09 22:49:28 +0000150
151/* Find out how many times the given word exists in the bag. */
sewardj250ec2e2008-02-15 22:02:30 +0000152UWord HG_(elemBag) ( WordBag*, UWord );
sewardjb4112022007-11-09 22:49:28 +0000153
154/* Delete a word from the bag. */
sewardj250ec2e2008-02-15 22:02:30 +0000155Bool HG_(delFromBag)( WordBag*, UWord );
sewardjb4112022007-11-09 22:49:28 +0000156
157/* Is the bag empty? */
158Bool HG_(isEmptyBag)( WordBag* );
159
160/* Does the bag have exactly one element? */
161Bool HG_(isSingletonTotalBag)( WordBag* );
162
163/* Return an arbitrary element from the bag. */
sewardj250ec2e2008-02-15 22:02:30 +0000164UWord HG_(anyElementOfBag)( WordBag* );
sewardjb4112022007-11-09 22:49:28 +0000165
166/* How many different / total elements are in the bag? */
sewardj250ec2e2008-02-15 22:02:30 +0000167UWord HG_(sizeUniqueBag)( WordBag* ); /* fast */
168UWord HG_(sizeTotalBag)( WordBag* ); /* warning: slow */
sewardjb4112022007-11-09 22:49:28 +0000169
170/* Iterating over the elements of a bag. */
171void HG_(initIterBag)( WordBag* );
sewardj250ec2e2008-02-15 22:02:30 +0000172Bool HG_(nextIterBag)( WordBag*, /*OUT*/UWord* pVal, /*OUT*/UWord* pCount );
sewardjb4112022007-11-09 22:49:28 +0000173void HG_(doneIterBag)( WordBag* );
174
175//------------------------------------------------------------------//
176//--- end WordBag (unboxed words only) ---//
177//--- Public interface ---//
178//------------------------------------------------------------------//
179
180#endif /* ! __HG_WORDFM_H */
181
182/*--------------------------------------------------------------------*/
183/*--- end hg_wordfm.h ---*/
184/*--------------------------------------------------------------------*/