blob: 806ea321b21262c33b538ec3323249589c7a7ae4 [file] [log] [blame]
sewardjd864eb92007-02-25 11:51:13 +00001
2/*--------------------------------------------------------------------*/
3/*--- An expandable array implementation. m_xarray.h ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2007-2007 OpenWorks LLP
11 info@open-works.co.uk
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31#include "pub_core_basics.h"
32#include "pub_core_libcbase.h"
33#include "pub_core_libcassert.h"
34#include "pub_core_libcprint.h"
35#include "pub_core_xarray.h" /* self */
36
37
sewardj7df15152007-02-25 15:04:40 +000038/* See pub_tool_xarray.h for details of what this is all about. */
sewardjd864eb92007-02-25 11:51:13 +000039
40struct _XArray {
41 void* (*alloc) ( SizeT ); /* alloc fn (nofail) */
42 void (*free) ( void* ); /* free fn */
njnb4cfa2f2007-03-28 01:27:05 +000043 Int (*cmpFn) ( void*, void* ); /* cmp fn (may be NULL) */
sewardjd864eb92007-02-25 11:51:13 +000044 Word elemSzB; /* element size in bytes */
45 void* arr; /* pointer to elements */
46 Word usedsizeE; /* # used elements in arr */
47 Word totsizeE; /* max size of arr, in elements */
48 Bool sorted; /* is it sorted? */
49};
50
51
52XArray* VG_(newXA) ( void*(*alloc_fn)(SizeT),
53 void(*free_fn)(void*),
54 Word elemSzB )
55{
56 struct _XArray* xa;
57 /* Implementation relies on Word being signed and (possibly)
58 on SizeT being unsigned. */
59 vg_assert( sizeof(Word) == sizeof(void*) );
60 vg_assert( ((Word)(-1)) < ((Word)(0)) );
61 vg_assert( ((SizeT)(-1)) > ((SizeT)(0)) );
62 /* check user-supplied info .. */
63 vg_assert(alloc_fn);
64 vg_assert(free_fn);
65 vg_assert(elemSzB > 0);
66 xa = alloc_fn( sizeof(struct _XArray) );
67 vg_assert(xa);
68 xa->alloc = alloc_fn;
69 xa->free = free_fn;
70 xa->cmpFn = NULL;
71 xa->elemSzB = elemSzB;
72 xa->usedsizeE = 0;
73 xa->totsizeE = 0;
74 xa->sorted = False;
75 xa->arr = NULL;
76 return xa;
77}
78
79void VG_(deleteXA) ( XArray* xao )
80{
81 struct _XArray* xa = (struct _XArray*)xao;
82 vg_assert(xa);
83 vg_assert(xa->free);
sewardje783ceb2007-08-28 05:19:16 +000084 if (xa->arr)
sewardjd864eb92007-02-25 11:51:13 +000085 xa->free(xa->arr);
86 xa->free(xa);
87}
88
njnb4cfa2f2007-03-28 01:27:05 +000089void VG_(setCmpFnXA) ( XArray* xao, Int (*compar)(void*,void*) )
sewardjd864eb92007-02-25 11:51:13 +000090{
91 struct _XArray* xa = (struct _XArray*)xao;
92 vg_assert(xa);
93 vg_assert(compar);
94 xa->cmpFn = compar;
95 xa->sorted = False;
96}
97
98inline void* VG_(indexXA) ( XArray* xao, Word n )
99{
100 struct _XArray* xa = (struct _XArray*)xao;
101 vg_assert(xa);
102 vg_assert(n >= 0);
103 vg_assert(n < xa->usedsizeE);
104 return ((char*)xa->arr) + n * xa->elemSzB;
105}
106
sewardj0f631482007-02-27 16:40:53 +0000107Int VG_(addToXA) ( XArray* xao, void* elem )
sewardjd864eb92007-02-25 11:51:13 +0000108{
109 struct _XArray* xa = (struct _XArray*)xao;
110 vg_assert(xa);
111 vg_assert(elem);
112 vg_assert(xa->totsizeE >= 0);
113 vg_assert(xa->usedsizeE >= 0 && xa->usedsizeE <= xa->totsizeE);
114 if (xa->usedsizeE == xa->totsizeE) {
115 void* tmp;
116 Word newsz;
117 if (xa->totsizeE == 0)
118 vg_assert(!xa->arr);
119 if (xa->totsizeE > 0)
120 vg_assert(xa->arr);
121 newsz = xa->totsizeE==0 ? 2 : 2 * xa->totsizeE;
122 if (0)
123 VG_(printf)("addToXA: increasing from %ld to %ld\n",
124 xa->totsizeE, newsz);
125 tmp = xa->alloc(newsz * xa->elemSzB);
126 vg_assert(tmp);
127 if (xa->usedsizeE > 0)
128 VG_(memcpy)(tmp, xa->arr, xa->usedsizeE * xa->elemSzB);
129 if (xa->arr)
130 xa->free(xa->arr);
131 xa->arr = tmp;
132 xa->totsizeE = newsz;
133 }
134 vg_assert(xa->usedsizeE < xa->totsizeE);
135 vg_assert(xa->arr);
136 VG_(memcpy)( ((UChar*)xa->arr) + xa->usedsizeE * xa->elemSzB,
137 elem, xa->elemSzB );
138 xa->usedsizeE++;
139 xa->sorted = False;
sewardj0f631482007-02-27 16:40:53 +0000140 return xa->usedsizeE-1;
sewardjd864eb92007-02-25 11:51:13 +0000141}
142
sewardjd864eb92007-02-25 11:51:13 +0000143void VG_(sortXA) ( XArray* xao )
144{
145 struct _XArray* xa = (struct _XArray*)xao;
146 vg_assert(xa);
147 vg_assert(xa->cmpFn);
njnb4cfa2f2007-03-28 01:27:05 +0000148 VG_(ssort)( xa->arr, xa->usedsizeE, xa->elemSzB, xa->cmpFn );
sewardjd864eb92007-02-25 11:51:13 +0000149 xa->sorted = True;
150}
151
152Bool VG_(lookupXA) ( XArray* xao, void* key, Word* first, Word* last )
153{
154 Word lo, mid, hi, cres;
155 void* midv;
156 struct _XArray* xa = (struct _XArray*)xao;
157 vg_assert(xa);
158 vg_assert(xa->cmpFn);
159 vg_assert(xa->sorted);
160 vg_assert(first);
161 vg_assert(last);
162 lo = 0;
163 hi = xa->usedsizeE-1;
164 while (True) {
165 /* current unsearched space is from lo to hi, inclusive. */
166 if (lo > hi) return False; /* not found */
167 mid = (lo + hi) / 2;
168 midv = VG_(indexXA)( xa, mid );
169 cres = xa->cmpFn( key, midv );
170 if (cres < 0) { hi = mid-1; continue; }
171 if (cres > 0) { lo = mid+1; continue; }
172 /* Found it, at mid. See how far we can expand this. */
173 vg_assert(xa->cmpFn( key, VG_(indexXA)(xa, lo) ) >= 0);
174 vg_assert(xa->cmpFn( key, VG_(indexXA)(xa, hi) ) <= 0);
175 *first = *last = mid;
176 while (*first > 0
177 && 0 == xa->cmpFn( key, VG_(indexXA)(xa, (*first)-1)))
178 (*first)--;
179 while (*last < xa->usedsizeE-1
180 && 0 == xa->cmpFn( key, VG_(indexXA)(xa, (*last)+1)))
181 (*last)++;
182 return True;
183 }
184}
185
186Word VG_(sizeXA) ( XArray* xao )
187{
188 struct _XArray* xa = (struct _XArray*)xao;
189 vg_assert(xa);
190 return xa->usedsizeE;
191}
192
193void VG_(dropTailXA) ( XArray* xao, Word n )
194{
195 struct _XArray* xa = (struct _XArray*)xao;
196 vg_assert(xa);
197 vg_assert(n >= 0);
198 vg_assert(n <= xa->usedsizeE);
199 xa->usedsizeE -= n;
200}
201
202
203/*--------------------------------------------------------------------*/
204/*--- end m_xarray.c ---*/
205/*--------------------------------------------------------------------*/