hashtable2.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * Copyright (c) 1999-2006 Apple Inc. All Rights Reserved.
  3. *
  4. * @APPLE_LICENSE_HEADER_START@
  5. *
  6. * This file contains Original Code and/or Modifications of Original Code
  7. * as defined in and that are subject to the Apple Public Source License
  8. * Version 2.0 (the 'License'). You may not use this file except in
  9. * compliance with the License. Please obtain a copy of the License at
  10. * http://www.opensource.apple.com/apsl/ and read it before using this
  11. * file.
  12. *
  13. * The Original Code and all software distributed under the License are
  14. * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  15. * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  16. * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  18. * Please see the License for the specific language governing rights and
  19. * limitations under the License.
  20. *
  21. * @APPLE_LICENSE_HEADER_END@
  22. */
  23. /*
  24. hashtable2.h
  25. Scalable hash table.
  26. Copyright 1989-1996 NeXT Software, Inc.
  27. */
  28. #ifndef _OBJC_LITTLE_HASHTABLE_H_
  29. #define _OBJC_LITTLE_HASHTABLE_H_
  30. #ifndef _OBJC_PRIVATE_H_
  31. # define OBJC_HASH_AVAILABILITY \
  32. __OSX_DEPRECATED(10.0, 10.1, "NXHashTable is deprecated") \
  33. __IOS_UNAVAILABLE __TVOS_UNAVAILABLE \
  34. __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE
  35. #else
  36. # define OBJC_HASH_AVAILABILITY
  37. #endif
  38. #include <objc/objc.h>
  39. #include <stdint.h>
  40. #include <TargetConditionals.h>
  41. __BEGIN_DECLS
  42. /*************************************************************************
  43. * Hash tables of arbitrary data
  44. *************************************************************************/
  45. /* This module allows hashing of arbitrary data. Such data must be pointers or integers, and client is responsible for allocating/deallocating this data. A deallocation call-back is provided.
  46. The objective C class HashTable is preferred when dealing with (key, values) associations because it is easier to use in that situation.
  47. As well-behaved scalable data structures, hash tables double in size when they start becoming full, thus guaranteeing both average constant time access and linear size. */
  48. typedef struct {
  49. uintptr_t (* _Nonnull hash)(const void * _Nullable info,
  50. const void * _Nullable data);
  51. int (* _Nonnull isEqual)(const void * _Nullable info,
  52. const void * _Nullable data1,
  53. const void * _Nullable data2);
  54. void (* _Nonnull free)(const void * _Nullable info,
  55. void * _Nullable data);
  56. int style; /* reserved for future expansion; currently 0 */
  57. } NXHashTablePrototype;
  58. /* the info argument allows a certain generality, such as freeing according to some owner information */
  59. /* invariants assumed by the implementation:
  60. 1 - data1 = data2 => hash(data1) = hash(data2)
  61. when data varies over time, hash(data) must remain invariant
  62. e.g. if data hashes over a string key, the string must not be changed
  63. 2- isEqual (data1, data2) => data1= data2
  64. */
  65. typedef struct {
  66. const NXHashTablePrototype * _Nonnull prototype OBJC_HASH_AVAILABILITY;
  67. unsigned count OBJC_HASH_AVAILABILITY;
  68. unsigned nbBuckets OBJC_HASH_AVAILABILITY;
  69. void * _Nullable buckets OBJC_HASH_AVAILABILITY;
  70. const void * _Nullable info OBJC_HASH_AVAILABILITY;
  71. } NXHashTable OBJC_HASH_AVAILABILITY;
  72. /* private data structure; may change */
  73. OBJC_EXPORT NXHashTable * _Nonnull
  74. NXCreateHashTableFromZone (NXHashTablePrototype prototype, unsigned capacity,
  75. const void * _Nullable info, void * _Nullable z)
  76. OBJC_HASH_AVAILABILITY;
  77. OBJC_EXPORT NXHashTable * _Nonnull
  78. NXCreateHashTable (NXHashTablePrototype prototype, unsigned capacity,
  79. const void * _Nullable info)
  80. OBJC_HASH_AVAILABILITY;
  81. /* if hash is 0, pointer hash is assumed */
  82. /* if isEqual is 0, pointer equality is assumed */
  83. /* if free is 0, elements are not freed */
  84. /* capacity is only a hint; 0 creates a small table */
  85. /* info allows call backs to be very general */
  86. OBJC_EXPORT void
  87. NXFreeHashTable (NXHashTable * _Nonnull table)
  88. OBJC_HASH_AVAILABILITY;
  89. /* calls free for each data, and recovers table */
  90. OBJC_EXPORT void
  91. NXEmptyHashTable (NXHashTable * _Nonnull table)
  92. OBJC_HASH_AVAILABILITY;
  93. /* does not deallocate table nor data; keeps current capacity */
  94. OBJC_EXPORT void
  95. NXResetHashTable (NXHashTable * _Nonnull table)
  96. OBJC_HASH_AVAILABILITY;
  97. /* frees each entry; keeps current capacity */
  98. OBJC_EXPORT BOOL
  99. NXCompareHashTables (NXHashTable * _Nonnull table1,
  100. NXHashTable * _Nonnull table2)
  101. OBJC_HASH_AVAILABILITY;
  102. /* Returns YES if the two sets are equal (each member of table1 in table2, and table have same size) */
  103. OBJC_EXPORT NXHashTable * _Nonnull
  104. NXCopyHashTable (NXHashTable * _Nonnull table)
  105. OBJC_HASH_AVAILABILITY;
  106. /* makes a fresh table, copying data pointers, not data itself. */
  107. OBJC_EXPORT unsigned
  108. NXCountHashTable (NXHashTable * _Nonnull table)
  109. OBJC_HASH_AVAILABILITY;
  110. /* current number of data in table */
  111. OBJC_EXPORT int
  112. NXHashMember (NXHashTable * _Nonnull table, const void * _Nullable data)
  113. OBJC_HASH_AVAILABILITY;
  114. /* returns non-0 iff data is present in table.
  115. Example of use when the hashed data is a struct containing the key,
  116. and when the callee only has a key:
  117. MyStruct pseudo;
  118. pseudo.key = myKey;
  119. return NXHashMember (myTable, &pseudo)
  120. */
  121. OBJC_EXPORT void * _Nullable
  122. NXHashGet (NXHashTable * _Nonnull table, const void * _Nullable data)
  123. OBJC_HASH_AVAILABILITY;
  124. /* return original table data or NULL.
  125. Example of use when the hashed data is a struct containing the key,
  126. and when the callee only has a key:
  127. MyStruct pseudo;
  128. MyStruct *original;
  129. pseudo.key = myKey;
  130. original = NXHashGet (myTable, &pseudo)
  131. */
  132. OBJC_EXPORT void * _Nullable
  133. NXHashInsert (NXHashTable * _Nonnull table, const void * _Nullable data)
  134. OBJC_HASH_AVAILABILITY;
  135. /* previous data or NULL is returned. */
  136. OBJC_EXPORT void * _Nullable
  137. NXHashInsertIfAbsent (NXHashTable * _Nonnull table, const void * _Nullable data)
  138. OBJC_HASH_AVAILABILITY;
  139. /* If data already in table, returns the one in table
  140. else adds argument to table and returns argument. */
  141. OBJC_EXPORT void * _Nullable
  142. NXHashRemove (NXHashTable * _Nonnull table, const void * _Nullable data)
  143. OBJC_HASH_AVAILABILITY;
  144. /* previous data or NULL is returned */
  145. /* Iteration over all elements of a table consists in setting up an iteration state and then to progress until all entries have been visited. An example of use for counting elements in a table is:
  146. unsigned count = 0;
  147. MyData *data;
  148. NXHashState state = NXInitHashState(table);
  149. while (NXNextHashState(table, &state, &data)) {
  150. count++;
  151. }
  152. */
  153. typedef struct {int i; int j;} NXHashState OBJC_HASH_AVAILABILITY;
  154. /* callers should not rely on actual contents of the struct */
  155. OBJC_EXPORT NXHashState
  156. NXInitHashState(NXHashTable * _Nonnull table)
  157. OBJC_HASH_AVAILABILITY;
  158. OBJC_EXPORT int
  159. NXNextHashState(NXHashTable * _Nonnull table, NXHashState * _Nonnull state,
  160. void * _Nullable * _Nonnull data) OBJC_HASH_AVAILABILITY;
  161. /* returns 0 when all elements have been visited */
  162. /*************************************************************************
  163. * Conveniences for writing hash, isEqual and free functions
  164. * and common prototypes
  165. *************************************************************************/
  166. OBJC_EXPORT uintptr_t
  167. NXPtrHash(const void * _Nullable info, const void * _Nullable data)
  168. OBJC_HASH_AVAILABILITY;
  169. /* scrambles the address bits; info unused */
  170. OBJC_EXPORT uintptr_t
  171. NXStrHash(const void * _Nullable info, const void * _Nullable data)
  172. OBJC_HASH_AVAILABILITY;
  173. /* string hashing; info unused */
  174. OBJC_EXPORT int
  175. NXPtrIsEqual(const void * _Nullable info, const void * _Nullable data1,
  176. const void * _Nullable data2)
  177. OBJC_HASH_AVAILABILITY;
  178. /* pointer comparison; info unused */
  179. OBJC_EXPORT int
  180. NXStrIsEqual(const void * _Nullable info, const void * _Nullable data1,
  181. const void * _Nullable data2)
  182. OBJC_HASH_AVAILABILITY;
  183. /* string comparison; NULL ok; info unused */
  184. OBJC_EXPORT void
  185. NXNoEffectFree(const void * _Nullable info, void * _Nullable data)
  186. OBJC_HASH_AVAILABILITY;
  187. /* no effect; info unused */
  188. OBJC_EXPORT void
  189. NXReallyFree(const void * _Nullable info, void * _Nullable data)
  190. OBJC_HASH_AVAILABILITY;
  191. /* frees it; info unused */
  192. /* The two following prototypes are useful for manipulating set of pointers or set of strings; For them free is defined as NXNoEffectFree */
  193. OBJC_EXPORT const NXHashTablePrototype NXPtrPrototype
  194. OBJC_HASH_AVAILABILITY;
  195. /* prototype when data is a pointer (void *) */
  196. OBJC_EXPORT const NXHashTablePrototype NXStrPrototype
  197. OBJC_HASH_AVAILABILITY;
  198. /* prototype when data is a string (char *) */
  199. /* following prototypes help describe mappings where the key is the first element of a struct and is either a pointer or a string.
  200. For example NXStrStructKeyPrototype can be used to hash pointers to Example, where Example is:
  201. typedef struct {
  202. char *key;
  203. int data1;
  204. ...
  205. } Example
  206. For the following prototypes, free is defined as NXReallyFree.
  207. */
  208. OBJC_EXPORT const NXHashTablePrototype NXPtrStructKeyPrototype
  209. OBJC_HASH_AVAILABILITY;
  210. OBJC_EXPORT const NXHashTablePrototype NXStrStructKeyPrototype
  211. OBJC_HASH_AVAILABILITY;
  212. #if !__OBJC2__ && !TARGET_OS_WIN32
  213. /*************************************************************************
  214. * Unique strings and buffers
  215. *************************************************************************/
  216. /* Unique strings allows C users to enjoy the benefits of Lisp's atoms:
  217. A unique string is a string that is allocated once for all (never de-allocated) and that has only one representant (thus allowing comparison with == instead of strcmp). A unique string should never be modified (and in fact some memory protection is done to ensure that). In order to more explicitly insist on the fact that the string has been uniqued, a synonym of (const char *) has been added, NXAtom. */
  218. typedef const char *NXAtom OBJC_HASH_AVAILABILITY;
  219. OBJC_EXPORT NXAtom _Nullable
  220. NXUniqueString(const char * _Nullable buffer)
  221. OBJC_HASH_AVAILABILITY;
  222. /* assumes that buffer is \0 terminated, and returns
  223. a previously created string or a new string that is a copy of buffer.
  224. If NULL is passed returns NULL.
  225. Returned string should never be modified. To ensure this invariant,
  226. allocations are made in a special read only zone. */
  227. OBJC_EXPORT NXAtom _Nonnull
  228. NXUniqueStringWithLength(const char * _Nullable buffer, int length)
  229. OBJC_HASH_AVAILABILITY;
  230. /* assumes that buffer is a non NULL buffer of at least
  231. length characters. Returns a previously created string or
  232. a new string that is a copy of buffer.
  233. If buffer contains \0, string will be truncated.
  234. As for NXUniqueString, returned string should never be modified. */
  235. OBJC_EXPORT NXAtom _Nullable
  236. NXUniqueStringNoCopy(const char * _Nullable string)
  237. OBJC_HASH_AVAILABILITY;
  238. /* If there is already a unique string equal to string, returns the original.
  239. Otherwise, string is entered in the table, without making a copy. Argument should then never be modified. */
  240. OBJC_EXPORT char * _Nullable
  241. NXCopyStringBuffer(const char * _Nullable buffer)
  242. OBJC_HASH_AVAILABILITY;
  243. /* given a buffer, allocates a new string copy of buffer.
  244. Buffer should be \0 terminated; returned string is \0 terminated. */
  245. OBJC_EXPORT char * _Nullable
  246. NXCopyStringBufferFromZone(const char * _Nullable buffer, void * _Nullable z)
  247. OBJC_HASH_AVAILABILITY;
  248. /* given a buffer, allocates a new string copy of buffer.
  249. Buffer should be \0 terminated; returned string is \0 terminated. */
  250. #endif
  251. __END_DECLS
  252. #endif /* _OBJC_LITTLE_HASHTABLE_H_ */