ht.h
上传用户:awang829
上传日期:2019-07-14
资源大小:2356k
文件大小:28k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* Copyright (c) 2002, Christopher Clark.
  2.  * Copyright (c) 2005-2006, Nick Mathewson.
  3.  * Copyright (c) 2007-2009, The Tor Project, Inc. */
  4. /* See license at end. */
  5. /* Based on ideas by Christopher Clark and interfaces from Niels Provos. */
  6. #ifndef _TOR_HT_H
  7. #define _TOR_HT_H
  8. #define HT_HEAD(name, type)                                             
  9.   struct name {                                                         
  10.     /* The hash table itself. */                                        
  11.     struct type **hth_table;                                            
  12.     /* How long is the hash table? */                                   
  13.     unsigned hth_table_length;                                          
  14.     /* How many elements does the table contain? */                     
  15.     unsigned hth_n_entries;                                             
  16.     /* How many elements will we allow in the table before resizing it? */ 
  17.     unsigned hth_load_limit;                                            
  18.     /* Position of hth_table_length in the primes table. */             
  19.     int hth_prime_idx;                                                  
  20.   }
  21. #define HT_INITIALIZER()                        
  22.   { NULL, 0, 0, 0, -1 }
  23. #define HT_ENTRY(type)                          
  24.   struct {                                      
  25.     struct type *hte_next;                      
  26.     unsigned hte_hash;                          
  27.   }
  28. #define HT_EMPTY(head)                          
  29.   ((head)->hth_n_entries == 0)
  30. /* Helper: alias for the bucket containing 'elm'. */
  31. #define _HT_BUCKET(head, field, elm)                                    
  32.   ((head)->hth_table[elm->field.hte_hash % head->hth_table_length])
  33. /* How many elements in 'head'? */
  34. #define HT_SIZE(head)                           
  35.   ((head)->hth_n_entries)
  36. #define HT_FIND(name, head, elm)     name##_HT_FIND((head), (elm))
  37. #define HT_INSERT(name, head, elm)   name##_HT_INSERT((head), (elm))
  38. #define HT_REPLACE(name, head, elm)  name##_HT_REPLACE((head), (elm))
  39. #define HT_REMOVE(name, head, elm)   name##_HT_REMOVE((head), (elm))
  40. #define HT_START(name, head)         name##_HT_START(head)
  41. #define HT_NEXT(name, head, elm)     name##_HT_NEXT((head), (elm))
  42. #define HT_NEXT_RMV(name, head, elm) name##_HT_NEXT_RMV((head), (elm))
  43. #define HT_CLEAR(name, head)         name##_HT_CLEAR(head)
  44. #define HT_INIT(name, head)          name##_HT_INIT(head)
  45. /* Helper: */
  46. static INLINE unsigned
  47. ht_improve_hash(unsigned h)
  48. {
  49.   /* Aim to protect against poor hash functions by adding logic here
  50.    * - logic taken from java 1.4 hashtable source */
  51.   h += ~(h << 9);
  52.   h ^=  ((h >> 14) | (h << 18)); /* >>> */
  53.   h +=  (h << 4);
  54.   h ^=  ((h >> 10) | (h << 22)); /* >>> */
  55.   return h;
  56. }
  57. #if 0
  58. /** Basic string hash function, from Java standard String.hashCode(). */
  59. static INLINE unsigned
  60. ht_string_hash(const char *s)
  61. {
  62.   unsigned h = 0;
  63.   int m = 1;
  64.   while (*s) {
  65.     h += ((signed char)*s++)*m;
  66.     m = (m<<5)-1; /* m *= 31 */
  67.   }
  68.   return h;
  69. }
  70. #endif
  71. /** Basic string hash function, from Python's str.__hash__() */
  72. static INLINE unsigned
  73. ht_string_hash(const char *s)
  74. {
  75.   unsigned h;
  76.   const unsigned char *cp = (const unsigned char *)s;
  77.   h = *cp << 7;
  78.   while (*cp) {
  79.     h = (1000003*h) ^ *cp++;
  80.   }
  81.   /* This conversion truncates the length of the string, but that's ok. */
  82.   h ^= (unsigned)(cp-(const unsigned char*)s);
  83.   return h;
  84. }
  85. #define _HT_SET_HASH(elm, field, hashfn)        
  86.     (elm)->field.hte_hash = hashfn(elm)
  87. #define HT_FOREACH(x, name, head)                 
  88.   for ((x) = HT_START(name, head);                
  89.        (x) != NULL;                               
  90.        (x) = HT_NEXT(name, head, x))
  91. #define HT_PROTOTYPE(name, type, field, hashfn, eqfn)                   
  92.   int name##_HT_GROW(struct name *ht, unsigned min_capacity);           
  93.   void name##_HT_CLEAR(struct name *ht);                                
  94.   int _##name##_HT_REP_IS_BAD(const struct name *ht);                   
  95.   static INLINE void                                                    
  96.   name##_HT_INIT(struct name *head) {                                   
  97.     head->hth_table_length = 0;                                         
  98.     head->hth_table = NULL;                                             
  99.     head->hth_n_entries = 0;                                            
  100.     head->hth_load_limit = 0;                                           
  101.     head->hth_prime_idx = -1;                                           
  102.   }                                                                     
  103.   /* Helper: returns a pointer to the right location in the table       
  104.    * 'head' to find or insert the element 'elm'. */                     
  105.   static INLINE struct type **                                          
  106.   _##name##_HT_FIND_P(struct name *head, struct type *elm)              
  107.   {                                                                     
  108.     struct type **p;                                                    
  109.     if (!head->hth_table)                                               
  110.       return NULL;                                                      
  111.     p = &_HT_BUCKET(head, field, elm);                                  
  112.     while (*p) {                                                        
  113.       if (eqfn(*p, elm))                                                
  114.         return p;                                                       
  115.       p = &(*p)->field.hte_next;                                        
  116.     }                                                                   
  117.     return p;                                                           
  118.   }                                                                     
  119.   /* Return a pointer to the element in the table 'head' matching 'elm', 
  120.    * or NULL if no such element exists */                               
  121.   static INLINE struct type *                                           
  122.   name##_HT_FIND(const struct name *head, struct type *elm)             
  123.   {                                                                     
  124.     struct type **p;                                                    
  125.     struct name *h = (struct name *) head;                              
  126.     _HT_SET_HASH(elm, field, hashfn);                                   
  127.     p = _##name##_HT_FIND_P(h, elm);                                    
  128.     return p ? *p : NULL;                                               
  129.   }                                                                     
  130.   /* Insert the element 'elm' into the table 'head'.  Do not call this  
  131.    * function if the table might already contain a matching element. */ 
  132.   static INLINE void                                                    
  133.   name##_HT_INSERT(struct name *head, struct type *elm)                 
  134.   {                                                                     
  135.     struct type **p;                                                    
  136.     if (!head->hth_table || head->hth_n_entries >= head->hth_load_limit) 
  137.       name##_HT_GROW(head, head->hth_n_entries+1);                      
  138.     ++head->hth_n_entries;                                              
  139.     _HT_SET_HASH(elm, field, hashfn);                                   
  140.     p = &_HT_BUCKET(head, field, elm);                                  
  141.     elm->field.hte_next = *p;                                           
  142.     *p = elm;                                                           
  143.   }                                                                     
  144.   /* Insert the element 'elm' into the table 'head'. If there already   
  145.    * a matching element in the table, replace that element and return   
  146.    * it. */                                                             
  147.   static INLINE struct type *                                           
  148.   name##_HT_REPLACE(struct name *head, struct type *elm)                
  149.   {                                                                     
  150.     struct type **p, *r;                                                
  151.     if (!head->hth_table || head->hth_n_entries >= head->hth_load_limit) 
  152.       name##_HT_GROW(head, head->hth_n_entries+1);                      
  153.     _HT_SET_HASH(elm, field, hashfn);                                   
  154.     p = _##name##_HT_FIND_P(head, elm);                                 
  155.     r = *p;                                                             
  156.     *p = elm;                                                           
  157.     if (r && (r!=elm)) {                                                
  158.       elm->field.hte_next = r->field.hte_next;                          
  159.       r->field.hte_next = NULL;                                         
  160.       return r;                                                         
  161.     } else {                                                            
  162.       ++head->hth_n_entries;                                            
  163.       return NULL;                                                      
  164.     }                                                                   
  165.   }                                                                     
  166.   /* Remove any element matching 'elm' from the table 'head'.  If such  
  167.    * an element is found, return it; otherwise return NULL. */          
  168.   static INLINE struct type *                                           
  169.   name##_HT_REMOVE(struct name *head, struct type *elm)                 
  170.   {                                                                     
  171.     struct type **p, *r;                                                
  172.     _HT_SET_HASH(elm, field, hashfn);                                   
  173.     p = _##name##_HT_FIND_P(head,elm);                                  
  174.     if (!p || !*p)                                                      
  175.       return NULL;                                                      
  176.     r = *p;                                                             
  177.     *p = r->field.hte_next;                                             
  178.     r->field.hte_next = NULL;                                           
  179.     --head->hth_n_entries;                                              
  180.     return r;                                                           
  181.   }                                                                     
  182.   /* Invoke the function 'fn' on every element of the table 'head',     
  183.    * using 'data' as its second argument.  If the function returns      
  184.    * nonzero, remove the most recently examined element before invoking 
  185.    * the function again. */                                             
  186.   static INLINE void                                                    
  187.   name##_HT_FOREACH_FN(struct name *head,                               
  188.                        int (*fn)(struct type *, void *),                
  189.                        void *data)                                      
  190.   {                                                                     
  191.     unsigned idx;                                                       
  192.     int remove;                                                         
  193.     struct type **p, **nextp, *next;                                    
  194.     if (!head->hth_table)                                               
  195.       return;                                                           
  196.     for (idx=0; idx < head->hth_table_length; ++idx) {                  
  197.       p = &head->hth_table[idx];                                        
  198.       while (*p) {                                                      
  199.         nextp = &(*p)->field.hte_next;                                  
  200.         next = *nextp;                                                  
  201.         remove = fn(*p, data);                                          
  202.         if (remove) {                                                   
  203.           --head->hth_n_entries;                                        
  204.           *p = next;                                                    
  205.         } else {                                                        
  206.           p = nextp;                                                    
  207.         }                                                               
  208.       }                                                                 
  209.     }                                                                   
  210.   }                                                                     
  211.   /* Return a pointer to the first element in the table 'head', under   
  212.    * an arbitrary order.  This order is stable under remove operations, 
  213.    * but not under others. If the table is empty, return NULL. */       
  214.   static INLINE struct type **                                          
  215.   name##_HT_START(struct name *head)                                    
  216.   {                                                                     
  217.     unsigned b = 0;                                                     
  218.     while (b < head->hth_table_length) {                                
  219.       if (head->hth_table[b])                                           
  220.         return &head->hth_table[b];                                     
  221.       ++b;                                                              
  222.     }                                                                   
  223.     return NULL;                                                        
  224.   }                                                                     
  225.   /* Return the next element in 'head' after 'elm', under the arbitrary 
  226.    * order used by HT_START.  If there are no more elements, return     
  227.    * NULL.  If 'elm' is to be removed from the table, you must call     
  228.    * this function for the next value before you remove it.             
  229.    */                                                                   
  230.   static INLINE struct type **                                          
  231.   name##_HT_NEXT(struct name *head, struct type **elm)                  
  232.   {                                                                     
  233.     if ((*elm)->field.hte_next) {                                       
  234.       return &(*elm)->field.hte_next;                                   
  235.     } else {                                                            
  236.       unsigned b = ((*elm)->field.hte_hash % head->hth_table_length)+1; 
  237.       while (b < head->hth_table_length) {                              
  238.         if (head->hth_table[b])                                         
  239.           return &head->hth_table[b];                                   
  240.         ++b;                                                            
  241.       }                                                                 
  242.       return NULL;                                                      
  243.     }                                                                   
  244.   }                                                                     
  245.   static INLINE struct type **                                          
  246.   name##_HT_NEXT_RMV(struct name *head, struct type **elm)              
  247.   {                                                                     
  248.     unsigned h = (*elm)->field.hte_hash;                                
  249.     *elm = (*elm)->field.hte_next;                                      
  250.     --head->hth_n_entries;                                              
  251.     if (*elm) {                                                         
  252.       return elm;                                                       
  253.     } else {                                                            
  254.       unsigned b = (h % head->hth_table_length)+1;                      
  255.       while (b < head->hth_table_length) {                              
  256.         if (head->hth_table[b])                                         
  257.           return &head->hth_table[b];                                   
  258.         ++b;                                                            
  259.       }                                                                 
  260.       return NULL;                                                      
  261.     }                                                                   
  262.   }
  263. #define HT_GENERATE(name, type, field, hashfn, eqfn, load, mallocfn,    
  264.                     reallocfn, freefn)                                  
  265.   static unsigned name##_PRIMES[] = {                                   
  266.     53, 97, 193, 389,                                                   
  267.     769, 1543, 3079, 6151,                                              
  268.     12289, 24593, 49157, 98317,                                         
  269.     196613, 393241, 786433, 1572869,                                    
  270.     3145739, 6291469, 12582917, 25165843,                               
  271.     50331653, 100663319, 201326611, 402653189,                          
  272.     805306457, 1610612741                                               
  273.   };                                                                    
  274.   static unsigned name##_N_PRIMES =                                     
  275.     (unsigned)(sizeof(name##_PRIMES)/sizeof(name##_PRIMES[0]));         
  276.   /* Expand the internal table of 'head' until it is large enough to    
  277.    * hold 'size' elements.  Return 0 on success, -1 on allocation       
  278.    * failure. */                                                        
  279.   int                                                                   
  280.   name##_HT_GROW(struct name *head, unsigned size)                      
  281.   {                                                                     
  282.     unsigned new_len, new_load_limit;                                   
  283.     int prime_idx;                                                      
  284.     struct type **new_table;                                            
  285.     if (head->hth_prime_idx == (int)name##_N_PRIMES - 1)                
  286.       return 0;                                                         
  287.     if (head->hth_load_limit > size)                                    
  288.       return 0;                                                         
  289.     prime_idx = head->hth_prime_idx;                                    
  290.     do {                                                                
  291.       new_len = name##_PRIMES[++prime_idx];                             
  292.       new_load_limit = (unsigned)(load*new_len);                        
  293.     } while (new_load_limit <= size &&                                  
  294.              prime_idx < (int)name##_N_PRIMES);                         
  295.     if ((new_table = mallocfn(new_len*sizeof(struct type*)))) {         
  296.       unsigned b;                                                       
  297.       memset(new_table, 0, new_len*sizeof(struct type*));               
  298.       for (b = 0; b < head->hth_table_length; ++b) {                    
  299.         struct type *elm, *next;                                        
  300.         unsigned b2;                                                    
  301.         elm = head->hth_table[b];                                       
  302.         while (elm) {                                                   
  303.           next = elm->field.hte_next;                                   
  304.           b2 = elm->field.hte_hash % new_len;                           
  305.           elm->field.hte_next = new_table[b2];                          
  306.           new_table[b2] = elm;                                          
  307.           elm = next;                                                   
  308.         }                                                               
  309.       }                                                                 
  310.       if (head->hth_table)                                              
  311.         freefn(head->hth_table);                                        
  312.       head->hth_table = new_table;                                      
  313.     } else {                                                            
  314.       unsigned b, b2;                                                   
  315.       new_table = reallocfn(head->hth_table, new_len*sizeof(struct type*)); 
  316.       if (!new_table) return -1;                                        
  317.       memset(new_table + head->hth_table_length, 0,                     
  318.              (new_len - head->hth_table_length)*sizeof(struct type*));  
  319.       for (b=0; b < head->hth_table_length; ++b) {                      
  320.         struct type *e, **pE;                                           
  321.         for (pE = &new_table[b], e = *pE; e != NULL; e = *pE) {         
  322.           b2 = e->field.hte_hash % new_len;                             
  323.           if (b2 == b) {                                                
  324.             pE = &e->field.hte_next;                                    
  325.           } else {                                                      
  326.             *pE = e->field.hte_next;                                    
  327.             e->field.hte_next = new_table[b2];                          
  328.             new_table[b2] = e;                                          
  329.           }                                                             
  330.         }                                                               
  331.       }                                                                 
  332.       head->hth_table = new_table;                                      
  333.     }                                                                   
  334.     head->hth_table_length = new_len;                                   
  335.     head->hth_prime_idx = prime_idx;                                    
  336.     head->hth_load_limit = new_load_limit;                              
  337.     return 0;                                                           
  338.   }                                                                     
  339.   /* Free all storage held by 'head'.  Does not free 'head' itself, or  
  340.    * individual elements. */                                            
  341.   void                                                                  
  342.   name##_HT_CLEAR(struct name *head)                                    
  343.   {                                                                     
  344.     if (head->hth_table)                                                
  345.       freefn(head->hth_table);                                          
  346.     head->hth_table_length = 0;                                         
  347.     name##_HT_INIT(head);                                               
  348.   }                                                                     
  349.   /* Debugging helper: return false iff the representation of 'head' is 
  350.    * internally consistent. */                                          
  351.   int                                                                   
  352.   _##name##_HT_REP_IS_BAD(const struct name *head)                      
  353.   {                                                                     
  354.     unsigned n, i;                                                      
  355.     struct type *elm;                                                   
  356.     if (!head->hth_table_length) {                                      
  357.       if (!head->hth_table && !head->hth_n_entries &&                   
  358.           !head->hth_load_limit && head->hth_prime_idx == -1)           
  359.         return 0;                                                       
  360.       else                                                              
  361.         return 1;                                                       
  362.     }                                                                   
  363.     if (!head->hth_table || head->hth_prime_idx < 0 ||                  
  364.         !head->hth_load_limit)                                          
  365.       return 2;                                                         
  366.     if (head->hth_n_entries > head->hth_load_limit)                     
  367.       return 3;                                                         
  368.     if (head->hth_table_length != name##_PRIMES[head->hth_prime_idx])   
  369.       return 4;                                                         
  370.     if (head->hth_load_limit != (unsigned)(load*head->hth_table_length)) 
  371.       return 5;                                                         
  372.     for (n = i = 0; i < head->hth_table_length; ++i) {                  
  373.       for (elm = head->hth_table[i]; elm; elm = elm->field.hte_next) {  
  374.         if (elm->field.hte_hash != hashfn(elm))                         
  375.           return 1000 + i;                                              
  376.         if ((elm->field.hte_hash % head->hth_table_length) != i)        
  377.           return 10000 + i;                                             
  378.         ++n;                                                            
  379.       }                                                                 
  380.     }                                                                   
  381.     if (n != head->hth_n_entries)                                       
  382.       return 6;                                                         
  383.     return 0;                                                           
  384.   }
  385. /** Implements an over-optimized "find and insert if absent" block;
  386.  * not meant for direct usage by typical code, or usage outside the critical
  387.  * path.*/
  388. #define _HT_FIND_OR_INSERT(name, field, hashfn, head, eltype, elm, var, y, n) 
  389.   {                                                                     
  390.     struct name *_##var##_head = head;                                  
  391.     eltype **var;                                                       
  392.     if (!_##var##_head->hth_table ||                                    
  393.         _##var##_head->hth_n_entries >= _##var##_head->hth_load_limit)  
  394.       name##_HT_GROW(_##var##_head, _##var##_head->hth_n_entries+1);     
  395.     _HT_SET_HASH((elm), field, hashfn);                                
  396.     var = _##name##_HT_FIND_P(_##var##_head, (elm));                    
  397.     if (*var) {                                                         
  398.       y;                                                                
  399.     } else {                                                            
  400.       n;                                                                
  401.     }                                                                   
  402.   }
  403. #define _HT_FOI_INSERT(field, head, elm, newent, var)       
  404.   {                                                         
  405.     newent->field.hte_hash = (elm)->field.hte_hash;         
  406.     newent->field.hte_next = NULL;                          
  407.     *var = newent;                                          
  408.     ++((head)->hth_n_entries);                              
  409.   }
  410. /*
  411.  * Copyright 2005, Nick Mathewson.  Implementation logic is adapted from code
  412.  * by Christopher Clark, retrofit to allow drop-in memory management, and to
  413.  * use the same interface as Niels Provos's HT_H.  I'm not sure whether this
  414.  * is a derived work any more, but whether it is or not, the license below
  415.  * applies.
  416.  *
  417.  * Copyright (c) 2002, Christopher Clark
  418.  * All rights reserved.
  419.  *
  420.  * Redistribution and use in source and binary forms, with or without
  421.  * modification, are permitted provided that the following conditions
  422.  * are met:
  423.  *
  424.  * * Redistributions of source code must retain the above copyright
  425.  * notice, this list of conditions and the following disclaimer.
  426.  *
  427.  * * Redistributions in binary form must reproduce the above copyright
  428.  * notice, this list of conditions and the following disclaimer in the
  429.  * documentation and/or other materials provided with the distribution.
  430.  *
  431.  * * Neither the name of the original author; nor the names of any contributors
  432.  * may be used to endorse or promote products derived from this software
  433.  * without specific prior written permission.
  434.  *
  435.  *
  436.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  437.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  438.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  439.  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
  440.  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  441.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  442.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  443.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  444.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  445.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  446.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  447. */
  448. #endif