Guest User

Untitled

a guest
Dec 4th, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.57 KB | None | 0 0
  1. #define _XOPEN_SOURCE 500 /* Enable certain library functions (strdup) on linux. See feature_test_macros(7) */
  2.  
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <limits.h>
  6. #include <string.h>
  7.  
  8. struct entry_s {
  9. char *key;
  10. char *value;
  11. struct entry_s *next;
  12. };
  13.  
  14. typedef struct entry_s entry_t;
  15.  
  16. struct hashtable_s {
  17. int size;
  18. struct entry_s **table;
  19. };
  20.  
  21. typedef struct hashtable_s hashtable_t;
  22.  
  23.  
  24. /* Create a new hashtable. */
  25. hashtable_t *ht_create( int size ) {
  26.  
  27. hashtable_t *hashtable = NULL;
  28. int i;
  29.  
  30. if( size < 1 ) return NULL;
  31.  
  32. /* Allocate the table itself. */
  33. if( ( hashtable = malloc( sizeof( hashtable_t ) ) ) == NULL ) {
  34. return NULL;
  35. }
  36.  
  37. /* Allocate pointers to the head nodes. */
  38. if( ( hashtable->table = malloc( sizeof( entry_t * ) * size ) ) == NULL ) {
  39. return NULL;
  40. }
  41. for( i = 0; i < size; i++ ) {
  42. hashtable->table[i] = NULL;
  43. }
  44.  
  45. hashtable->size = size;
  46.  
  47. return hashtable;
  48. }
  49.  
  50. /* Hash a string for a particular hash table. */
  51. int ht_hash( hashtable_t *hashtable, char *key ) {
  52.  
  53. unsigned long int hashval;
  54. int i = 0;
  55.  
  56. /* Convert our string to an integer */
  57. while( hashval < ULONG_MAX && i < strlen( key ) ) {
  58. hashval = hashval << 8;
  59. hashval += key[ i ];
  60. i++;
  61. }
  62.  
  63. return hashval % hashtable->size;
  64. }
  65.  
  66. /* Create a key-value pair. */
  67. entry_t *ht_newpair( char *key, char *value ) {
  68. entry_t *newpair;
  69.  
  70. if( ( newpair = malloc( sizeof( entry_t ) ) ) == NULL ) {
  71. return NULL;
  72. }
  73.  
  74. if( ( newpair->key = strdup( key ) ) == NULL ) {
  75. return NULL;
  76. }
  77.  
  78. if( ( newpair->value = strdup( value ) ) == NULL ) {
  79. return NULL;
  80. }
  81.  
  82. newpair->next = NULL;
  83.  
  84. return newpair;
  85. }
  86.  
  87. /* Insert a key-value pair into a hash table. */
  88. void ht_set( hashtable_t *hashtable, char *key, char *value ) {
  89. int bin = 0;
  90. entry_t *newpair = NULL;
  91. entry_t *next = NULL;
  92. entry_t *last = NULL;
  93.  
  94. bin = ht_hash( hashtable, key );
  95.  
  96. next = hashtable->table[ bin ];
  97.  
  98. while( next != NULL && next->key != NULL && strcmp( key, next->key ) > 0 ) {
  99. last = next;
  100. next = next->next;
  101. }
  102.  
  103. /* There's already a pair. Let's replace that string. */
  104. if( next != NULL && next->key != NULL && strcmp( key, next->key ) == 0 ) {
  105.  
  106. free( next->value );
  107. next->value = strdup( value );
  108.  
  109. /* Nope, could't find it. Time to grow a pair. */
  110. } else {
  111. newpair = ht_newpair( key, value );
  112.  
  113. /* We're at the start of the linked list in this bin. */
  114. if( next == hashtable->table[ bin ] ) {
  115. newpair->next = next;
  116. hashtable->table[ bin ] = newpair;
  117.  
  118. /* We're at the end of the linked list in this bin. */
  119. } else if ( next == NULL ) {
  120. last->next = newpair;
  121.  
  122. /* We're in the middle of the list. */
  123. } else {
  124. newpair->next = next;
  125. last->next = newpair;
  126. }
  127. }
  128. }
  129.  
  130. /* Retrieve a key-value pair from a hash table. */
  131. char *ht_get( hashtable_t *hashtable, char *key ) {
  132. int bin = 0;
  133. entry_t *pair;
  134.  
  135. bin = ht_hash( hashtable, key );
  136.  
  137. /* Step through the bin, looking for our value. */
  138. pair = hashtable->table[ bin ];
  139. while( pair != NULL && pair->key != NULL && strcmp( key, pair->key ) > 0 ) {
  140. pair = pair->next;
  141. }
  142.  
  143. /* Did we actually find anything? */
  144. if( pair == NULL || pair->key == NULL || strcmp( key, pair->key ) != 0 ) {
  145. return NULL;
  146.  
  147. } else {
  148. return pair->value;
  149. }
  150.  
  151. }
  152.  
  153.  
  154. int main( int argc, char **argv ) {
  155.  
  156. hashtable_t *hashtable = ht_create( 65536 );
  157.  
  158. ht_set( hashtable, "key1", "inky" );
  159. ht_set( hashtable, "key2", "pinky" );
  160. ht_set( hashtable, "key3", "blinky" );
  161. ht_set( hashtable, "key4", "floyd" );
  162.  
  163. printf( "%s\n", ht_get( hashtable, "key1" ) );
  164. printf( "%s\n", ht_get( hashtable, "key2" ) );
  165. printf( "%s\n", ht_get( hashtable, "key3" ) );
  166. printf( "%s\n", ht_get( hashtable, "key4" ) );
  167.  
  168. return 0;
  169. }
Add Comment
Please, Sign In to add comment