1 /* Set operations on pointers
2 Copyright (C) 2004-2013 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
24 /* A pointer set is represented as a simple open-addressing hash
25 table. Simplifications: The hash code is based on the value of the
26 pointer, not what it points to. The number of buckets is always a
27 power of 2. Null pointers are a reserved value. Deletion is not
28 supported (yet). There is no mechanism for user control of hash
29 function, equality comparison, initial size, or resizing policy. */
34 size_t n_slots
; /* n_slots = 2^log_slots */
39 struct pointer_set_t
*pointer_set_create (void);
40 void pointer_set_destroy (struct pointer_set_t
*pset
);
41 int pointer_set_contains (const struct pointer_set_t
*pset
, const void *p
);
42 int pointer_set_insert (struct pointer_set_t
*pset
, const void *p
);
43 void pointer_set_traverse (const struct pointer_set_t
*,
44 bool (*) (const void *, void *),
46 bool pointer_set_lookup (const pointer_set_t
*, const void *, size_t *);
48 /* A pointer map is represented the same way as a pointer_set, so
49 the hash code is based on the address of the key, rather than
50 its contents. Null keys are a reserved value. Deletion is not
51 supported (yet). There is no mechanism for user control of hash
52 function, equality comparison, initial size, or resizing policy. */
55 class pointer_map
: protected pointer_set_t
62 T
*contains (const void *p
);
63 T
*insert (const void *p
, bool *existed_p
= NULL
);
64 void traverse (bool (*fn
) (const void *, T
*, void *), void *data
);
67 /* Allocate an empty pointer map. */
69 pointer_map
<T
>::pointer_map (void)
73 n_slots
= (size_t) 1 << log_slots
;
75 slots
= XCNEWVEC (const void *, n_slots
);
76 values
= XNEWVEC (T
, n_slots
);
79 /* Reclaims all memory associated with PMAP. */
81 pointer_map
<T
>::~pointer_map (void)
87 /* Returns a pointer to the value to which P maps, if PMAP contains P. P
88 must be nonnull. Return NULL if PMAP does not contain P.
90 Collisions are resolved by linear probing. */
93 pointer_map
<T
>::contains (const void *p
)
96 if (!pointer_set_lookup (this, p
, &n
))
101 /* Inserts P into PMAP if it wasn't already there. Returns a pointer
102 to the value. P must be nonnull. */
103 template <typename T
>
105 pointer_map
<T
>::insert (const void *p
, bool *existed_p
)
109 /* For simplicity, expand the map even if P is already there. This can be
110 superfluous but can happen at most once. */
111 /* ??? Fugly that we have to inline that here. */
112 if (n_elements
> n_slots
/ 4)
114 size_t old_n_slots
= n_slots
;
115 const void **old_keys
= slots
;
116 T
*old_values
= values
;
117 log_slots
= log_slots
+ 1;
118 n_slots
= n_slots
* 2;
119 slots
= XCNEWVEC (const void *, n_slots
);
120 values
= XNEWVEC (T
, n_slots
);
121 for (size_t i
= 0; i
< old_n_slots
; ++i
)
124 const void *key
= old_keys
[i
];
125 pointer_set_lookup (this, key
, &n
);
127 values
[n
] = old_values
[i
];
129 XDELETEVEC (old_keys
);
130 XDELETEVEC (old_values
);
133 if (!pointer_set_lookup (this, p
, &n
))
146 /* Pass each pointer in PMAP to the function in FN, together with the pointer
147 to the value and the fixed parameter DATA. If FN returns false, the
152 pointer_map
<T
>::traverse (bool (*fn
) (const void *, T
*, void *), void *data
)
154 for (size_t i
= 0; i
< n_slots
; ++i
)
155 if (slots
[i
] && !fn (slots
[i
], &values
[i
], data
))
160 struct pointer_map_t
;
161 pointer_map_t
*pointer_map_create (void);
162 void pointer_map_destroy (pointer_map_t
*pmap
);
164 void **pointer_map_contains (const pointer_map_t
*pmap
, const void *p
);
165 void **pointer_map_insert (pointer_map_t
*pmap
, const void *p
);
166 void pointer_map_traverse (const pointer_map_t
*,
167 bool (*) (const void *, void **, void *), void *);
170 #endif /* POINTER_SET_H */