/ include / CoreFoundation / NSBasicHash.h
NSBasicHash.h
 1  #import <Foundation/NSException.h>
 2  
 3  #define NUM_BUCKET_SIZES 64
 4  
 5  static const NSUInteger __NSBasicHashIPrimes[NUM_BUCKET_SIZES] = {
 6      0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723,
 7      2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607,
 8      214519, 346607, 561109, 907759, 1468927, 2376191, 3845119,
 9      6221311, 10066421, 16287743, 26354171, 42641881, 68996069,
10      111638519, 180634607, 292272623, 472907251,
11  #if __LP64__
12      765180413UL, 1238087663UL, 2003267557UL, 3241355263UL, 5244622819UL,
13  #if 0
14      8485977589UL, 13730600407UL, 22216578047UL, 35947178479UL,
15      58163756537UL, 94110934997UL, 152274691561UL, 246385626107UL,
16      398660317687UL, 645045943807UL, 1043706260983UL, 1688752204787UL,
17      2732458465769UL, 4421210670577UL, 7153669136377UL,
18      11574879807461UL, 18728548943849UL, 30303428750843UL
19  #endif
20  #endif
21  };
22  
23  static const NSUInteger __NSBasicHashCapacities[NUM_BUCKET_SIZES] = {
24      0, 3, 6, 11, 19, 32, 52, 85, 118, 155, 237, 390, 672, 1065,
25      1732, 2795, 4543, 7391, 12019, 19302, 31324, 50629, 81956,
26      132580, 214215, 346784, 561026, 907847, 1468567, 2376414,
27      3844982, 6221390, 10066379, 16287773, 26354132, 42641916,
28      68996399, 111638327, 180634415, 292272755,
29  #if __LP64__
30      472907503UL, 765180257UL, 1238087439UL, 2003267722UL, 3241355160UL,
31  #if 0
32      5244622578UL, 8485977737UL, 13730600347UL, 22216578100UL,
33      35947178453UL, 58163756541UL, 94110935011UL, 152274691274UL,
34      246385626296UL, 398660317578UL, 645045943559UL, 1043706261135UL,
35      1688752204693UL, 2732458465840UL, 4421210670552UL,
36      7153669136706UL, 11574879807265UL, 18728548943682UL
37  #endif
38  #endif
39  };
40  
41  static inline NSUInteger __NSBasicHashGetSizeIdx(NSUInteger size) {
42      for (NSUInteger idx = 0; idx < NUM_BUCKET_SIZES; idx++) {
43          if (__NSBasicHashCapacities[idx] > size) {
44              return idx;
45          }
46      }
47  
48      DEBUG_BREAK();
49      return NSNotFound;
50  }
51  
52  static inline void *NSBasicHashAllocate(NSUInteger count, size_t size, NSUInteger *capacity, NSUInteger *sizeidx, BOOL throwOnMallocFailure) {
53      *sizeidx = __NSBasicHashGetSizeIdx(count);
54      *capacity = __NSBasicHashIPrimes[*sizeidx];
55      void *buffer = calloc(*capacity, size);
56      if (buffer == NULL && throwOnMallocFailure) {
57          [NSException raise:NSMallocException format:@"Unable to allocate buffer"];
58      }
59      return buffer;
60  }
61  
62  static inline void *NSBasicHashGrow(NSUInteger count, size_t size, void *buffer, NSUInteger *capacity, NSUInteger *sizeidx, BOOL throwOnMallocFailure) {
63      if (*capacity < count) {
64          *sizeidx = __NSBasicHashGetSizeIdx(count);
65          *capacity = __NSBasicHashIPrimes[*sizeidx];
66          void *newBuffer = realloc(buffer, (*capacity) * size);
67          if (newBuffer == NULL && throwOnMallocFailure) {
68              free(buffer);
69              *capacity = 0;
70              [NSException raise:NSMallocException format:@"Unable to reallocate buffer"];
71          }
72          buffer = newBuffer;
73      }
74      return buffer;
75  }
76  
77  static inline void *NSBasicHashTrim(NSUInteger count, size_t size, void *buffer, NSUInteger *capacity, BOOL throwOnMallocFailure) {
78      if (*capacity > count) {
79          void *newBuffer = realloc(buffer, count * size);
80          if (newBuffer == NULL && throwOnMallocFailure) { // very sad day indeed if trimming causes malloc failure...
81              free(buffer);
82              *capacity = 0;
83              [NSException raise:NSMallocException format:@"Unable to reallocate buffer"];   
84          } else {
85              *capacity = count * size;
86          }
87          buffer = newBuffer;
88      }
89      return buffer;
90  }
91  
92  static inline void NSBasicHashDeallocate(void *buffer) {
93      if (buffer) {
94          free(buffer);
95      }
96  }