|
||||
File indexing completed on 2025-01-18 10:13:31
0001 0002 /*--------------------------------------------------------------------*/ 0003 /*--- OSet: a fast data structure with no dups. pub_tool_oset.h ---*/ 0004 /*--------------------------------------------------------------------*/ 0005 0006 /* 0007 This file is part of Valgrind, a dynamic binary instrumentation 0008 framework. 0009 0010 Copyright (C) 2005-2017 Nicholas Nethercote 0011 njn@valgrind.org 0012 0013 This program is free software; you can redistribute it and/or 0014 modify it under the terms of the GNU General Public License as 0015 published by the Free Software Foundation; either version 2 of the 0016 License, or (at your option) any later version. 0017 0018 This program is distributed in the hope that it will be useful, but 0019 WITHOUT ANY WARRANTY; without even the implied warranty of 0020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0021 General Public License for more details. 0022 0023 You should have received a copy of the GNU General Public License 0024 along with this program; if not, see <http://www.gnu.org/licenses/>. 0025 0026 The GNU General Public License is contained in the file COPYING. 0027 */ 0028 0029 #ifndef __PUB_TOOL_OSET_H 0030 #define __PUB_TOOL_OSET_H 0031 0032 #include "pub_tool_basics.h" // Word 0033 0034 // This module implements an ordered set, a data structure with fast 0035 // (eg. amortised log(n) or better) insertion, lookup and deletion of 0036 // elements. It does not allow duplicates, and will assert if you insert a 0037 // duplicate to an OSet. 0038 // 0039 // It has two interfaces. 0040 // 0041 // - The "OSetWord_" interface provides an easier-to-use interface for the 0042 // case where you just want to store UWord-sized values. The user 0043 // provides the allocation and deallocation functions, and possibly a 0044 // comparison function. 0045 // 0046 // - The "OSetGen_" interface provides a totally generic interface, which 0047 // allows any kind of structure to be put into the set. The user provides 0048 // the allocation and deallocation functions. Also, each element has a 0049 // key, which the lookup is done with. The key may be the whole element 0050 // (eg. in an OSet of integers, each integer serves both as an element and 0051 // a key), or it may be only part of it (eg. if the key is a single field 0052 // in a struct). The user can provide a function that compares an element 0053 // with a key; this is very flexible, and with the right comparison 0054 // function even a (non-overlapping) interval list can be created. But 0055 // the cost of calling a function for every comparison can be high during 0056 // lookup. If no comparison function is provided, we assume that keys are 0057 // unsigned words, and that the key is the first word in each 0058 // element. This fast comparison is suitable for an OSet containing 0059 // structs where the first element is an Addr, for example. 0060 // Do not assume fast comparison works properly with signed words. 0061 // A.o. iterating over the values will not return them in the correct 0062 // order. 0063 // 0064 // Each OSet interface also has an iterator, which makes it simple to 0065 // traverse all the nodes in order. Note that the iterator maintains state 0066 // and so is non-reentrant. 0067 // 0068 // Note that once you insert an element into an OSet, if you modify any part 0069 // of it looked at by your cmp() function, this may cause incorrect 0070 // behaviour as the sorted order maintained will be wrong. 0071 0072 /*--------------------------------------------------------------------*/ 0073 /*--- Types ---*/ 0074 /*--------------------------------------------------------------------*/ 0075 0076 typedef struct _OSet OSet; 0077 0078 // - OSetCmp_t: returns -1, 0 or 1 if key is <, == or > elem. 0079 typedef Word (*OSetCmp_t) ( const void* key, const void* elem ); 0080 0081 /*--------------------------------------------------------------------*/ 0082 /*--- Creating and destroying OSets (UWord) ---*/ 0083 /*--------------------------------------------------------------------*/ 0084 0085 // * Create: allocates and initialises the OSet. Never returns NULL. 0086 // Parameters: 0087 // - alloc_fn The allocation function used internally for allocating the 0088 // OSet and all its nodes. It must not return NULL (that is, 0089 // if it returns it must have succeeded.) 0090 // - cc Cost centre string used by 'alloc'. 0091 // - free_fn The deallocation function used internally for freeing nodes 0092 // called by VG_(OSetWord_Destroy)(). 0093 // 0094 // * Destroy: frees all nodes in the table, plus the memory used by 0095 // the table itself. The passed-in function is called on each node first 0096 // to allow the destruction of any attached resources; if NULL it is not 0097 // called. 0098 0099 extern OSet* VG_(OSetWord_Create) ( Alloc_Fn_t alloc_fn, const HChar* cc, 0100 Free_Fn_t free_fn ); 0101 extern void VG_(OSetWord_Destroy) ( OSet* os ); 0102 0103 /*--------------------------------------------------------------------*/ 0104 /*--- Operations on OSets (UWord) ---*/ 0105 /*--------------------------------------------------------------------*/ 0106 0107 // In everything that follows, the parameter 'key' is always the *address* 0108 // of the key, and 'elem' is *address* of the elem, as are the return values 0109 // of the functions that return elems. 0110 // 0111 // * Size: The number of elements in the set. 0112 // 0113 // * Contains: Determines if the value is in the set. 0114 // 0115 // * Insert: Inserts a new element into the set. Duplicates are forbidden, 0116 // and will cause assertion failures. 0117 // 0118 // * Remove: Removes the value from the set, if present. Returns a Bool 0119 // indicating if the value was removed. 0120 // 0121 // * ResetIter: Each OSet has an iterator. This resets it to point to the 0122 // first element in the OSet. 0123 // 0124 // * Next: Copies the next value according to the OSet's iterator into &val, 0125 // advances the iterator by one, and returns True; the elements are 0126 // visited in increasing order of unsigned words (UWord). Or, returns 0127 // False if the iterator has reached the set's end. 0128 // 0129 // You can thus iterate in order through a set like this: 0130 // 0131 // Word val; 0132 // VG_(OSetWord_ResetIter)(oset); 0133 // while ( VG_(OSetWord_Next)(oset, &val) ) { 0134 // ... do stuff with 'val' ... 0135 // } 0136 // 0137 // Note that iterators are cleared any time an element is inserted or 0138 // removed from the OSet, to avoid possible mayhem caused by the iterator 0139 // getting out of sync with the OSet's contents. "Cleared" means that 0140 // they will return False if VG_(OSetWord_Next)() is called without an 0141 // intervening call to VG_(OSetWord_ResetIter)(). 0142 0143 extern Word VG_(OSetWord_Size) ( const OSet* os ); 0144 extern void VG_(OSetWord_Insert) ( OSet* os, UWord val ); 0145 extern Bool VG_(OSetWord_Contains) ( const OSet* os, UWord val ); 0146 extern Bool VG_(OSetWord_Remove) ( OSet* os, UWord val ); 0147 extern void VG_(OSetWord_ResetIter) ( OSet* os ); 0148 extern Bool VG_(OSetWord_Next) ( OSet* os, /*OUT*/UWord* val ); 0149 0150 0151 /*--------------------------------------------------------------------*/ 0152 /*--- Creating and destroying OSets and OSet members (Gen) ---*/ 0153 /*--------------------------------------------------------------------*/ 0154 0155 // * Create: allocates and initialises the OSet. Never returns NULL. 0156 // Parameters: 0157 // - keyOff The offset of the key within the element. 0158 // - cmp The comparison function between keys and elements, or NULL 0159 // if the OSet should use fast comparisons. 0160 // - alloc_fn The allocation function used for allocating the OSet itself; 0161 // It must not return NULL (that is, if it returns it must 0162 // have succeeded.) 0163 // If a pool allocator is used, it's called to allocate pool of 0164 // nodes. 0165 // If no pool allocator is used, it's called for each 0166 // invocation of VG_(OSetGen_AllocNode)(). 0167 // - cc Cost centre string used by 'alloc'. 0168 // - free_fn If no pool allocator is used, this is the deallocation 0169 // function used by VG_(OSetGen_FreeNode)() and 0170 // VG_(OSetGen_Destroy)(). 0171 // If a pool allocator is used, the memory used by the nodes is 0172 // deallocated when the pool is deleted. 0173 // (for more details about pool allocators, see pub_tool_poolalloc.h). 0174 // 0175 // 0176 // If cmp is NULL, keyOff must be zero. This is checked. 0177 // 0178 // * Destroy: frees all nodes in the table, plus the memory used by 0179 // the table itself. The passed-in function is called on each node first 0180 // to allow the destruction of any attached resources; if NULL it is not 0181 // called. 0182 // 0183 // * AllocNode: Allocate and zero memory for a node to go into the OSet. 0184 // If a pool allocator is used, it uses the pool allocator to allocate a node. 0185 // Otherwise, uses the alloc function given to VG_(OSetGen_Create)() to 0186 // allocate a node which is big enough for both an element and the OSet 0187 // metadata. 0188 // Not all elements in one OSet have to be the same size. 0189 // However, if a pool allocator is used, elements will all have a size equal 0190 // to the max user data size given at creation + the node meta data size. 0191 // 0192 // Note that the element allocated will be at most word-aligned, which may 0193 // be less aligned than the element type would normally be. 0194 // 0195 // * FreeNode: Deallocate a node allocated with OSetGen_AllocNode(). Using 0196 // a deallocation function (such as VG_(free)()) directly will likely 0197 // lead to assertions in Valgrind's allocator. 0198 0199 extern OSet* VG_(OSetGen_Create) ( PtrdiffT keyOff, OSetCmp_t cmp, 0200 Alloc_Fn_t alloc_fn, const HChar* cc, 0201 Free_Fn_t free_fn); 0202 0203 0204 extern OSet* VG_(OSetGen_Create_With_Pool) ( PtrdiffT keyOff, OSetCmp_t cmp, 0205 Alloc_Fn_t alloc_fn, 0206 const HChar* cc, 0207 Free_Fn_t free_fn, 0208 SizeT poolSize, 0209 SizeT maxEltSize); 0210 // Same as VG_(OSetGen_Create) but created OSet will use a pool allocator to 0211 // allocate the nodes. 0212 // The node size is the sum of a fixed small meta data size needed for OSet 0213 // + the size of the user data element. 0214 // The maximum size for the user data element is specified by maxEltSize. 0215 // (if poolSize is 0, maxEltSize is not relevant for the OSet). 0216 // It is interesting to use a pool allocator when an OSet has many elements, 0217 // and these elements have a small fixed size, or have a variable size, but 0218 // always <= than a (small) maximum value. 0219 // In such a case, allocating the nodes in pools reduces significantly 0220 // the memory overhead needed by each node. 0221 // When a node is freed (i.e. OSetGen_Freenode is called), the node is 0222 // put back in the pool allocator free list (for sub-sequent re-use by 0223 // OSetGen_AllocNode). Note that the pool memory is only released when 0224 // the pool is destroyed : calls to VG_(OSetGen_Free) do not cause 0225 // any calls to OSetFree_t _free function. 0226 // If there are several OSet managing similar such elements, it might be 0227 // interesting to use a shared pool for these OSet. 0228 // To have multiple OSets sharing a pool allocator, create the first OSet 0229 // with VG_(OSetGen_Create_With_Pool). Create subsequent OSet with 0230 // VG_(OSetGen_EmptyClone). 0231 0232 extern void VG_(OSetGen_Destroy) ( OSet* os ); 0233 extern void* VG_(OSetGen_AllocNode) ( const OSet* os, SizeT elemSize ); 0234 extern void VG_(OSetGen_FreeNode) ( const OSet* os, void* elem ); 0235 0236 extern OSet* VG_(OSetGen_EmptyClone) (const OSet* os); 0237 // Creates a new empty OSet. 0238 // The new OSet will have the same characteristics as os. 0239 // If os uses a pool allocator, this pool allocator will be shared with 0240 // the new OSet. A shared pool allocator is only deleted (and its memory is 0241 // released) when the last OSet using the shared pool is destroyed. 0242 0243 /*-------------------------------------------------------------------*/ 0244 /*--- Operations on OSets (Gen) ---*/ 0245 /*--------------------------------------------------------------------*/ 0246 0247 // In everything that follows, the parameter 'key' is always the *address* 0248 // of the key, and 'elem' is *address* of the elem, as are the return values 0249 // of the functions that return elems. 0250 // 0251 // * Size: The number of elements in the set. 0252 // 0253 // * Insert: Inserts a new element into the set. Note that 'elem' must 0254 // have been allocated using VG_(OSetGen_AllocNode)(), otherwise you will 0255 // get assertion failures about "bad magic". Duplicates are forbidden, 0256 // and will also cause assertion failures. 0257 // 0258 // * Contains: Determines if any element in the OSet matches the key. 0259 // 0260 // * Lookup: Returns a pointer to the element matching the key, if there is 0261 // one, otherwise returns NULL. 0262 // 0263 // * LookupWithCmp: Like Lookup, but you specify the comparison function, 0264 // which overrides the OSet's normal one. 0265 // 0266 // * Remove: Removes the element matching the key, if there is one. Returns 0267 // NULL if no element matches the key. 0268 // 0269 // * ResetIter: Each OSet has an iterator. This resets it to point to the 0270 // first element in the OSet. 0271 // 0272 // * ResetIterAt: Like ResetIter, but instead of resetting the iterator to the 0273 // smallest element, it resets the iterator to point to the smallest element 0274 // in the set whose key is greater-than-or-equal to the given key. (In many 0275 // cases this will be the element whose key equals that of the given key.) 0276 // 0277 // * Next: Returns a pointer to the element pointed to by the OSet's 0278 // iterator, and advances the iterator by one; the elements are visited 0279 // in order. Or, returns NULL if the iterator has reached the OSet's end. 0280 // 0281 // You can thus iterate in order through a set like this: 0282 // 0283 // VG_(OSetGen_ResetIter)(oset); 0284 // while ( (elem = VG_(OSetGen_Next)(oset)) ) { 0285 // ... do stuff with 'elem' ... 0286 // } 0287 // 0288 // Note that iterators are cleared any time an element is inserted or 0289 // removed from the OSet, to avoid possible mayhem caused by the iterator 0290 // getting out of sync with the OSet's contents. "Cleared" means that 0291 // they will return NULL if VG_(OSetGen_Next)() is called without an 0292 // intervening call to VG_(OSetGen_ResetIter)(). 0293 0294 extern UInt VG_(OSetGen_Size) ( const OSet* os ); 0295 extern void VG_(OSetGen_Insert) ( OSet* os, void* elem ); 0296 extern Bool VG_(OSetGen_Contains) ( const OSet* os, const void* key ); 0297 extern void* VG_(OSetGen_Lookup) ( const OSet* os, const void* key ); 0298 extern void* VG_(OSetGen_LookupWithCmp)( OSet* os, 0299 const void* key, OSetCmp_t cmp ); 0300 extern void* VG_(OSetGen_Remove) ( OSet* os, const void* key ); 0301 extern void VG_(OSetGen_ResetIter) ( OSet* os ); 0302 extern void VG_(OSetGen_ResetIterAt) ( OSet* os, const void* key ); 0303 extern void* VG_(OSetGen_Next) ( OSet* os ); 0304 0305 0306 #endif // __PUB_TOOL_OSET_H 0307 0308 /*--------------------------------------------------------------------*/ 0309 /*--- end ---*/ 0310 /*--------------------------------------------------------------------*/
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |