home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / sql / hash_filo.h < prev    next >
C/C++ Source or Header  |  2000-08-31  |  3KB  |  132 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16.  
  17.  
  18. /*
  19. ** A class for static sized hash tables where old entries are deleted in
  20. ** first-in-last-out to usage.
  21. */
  22.  
  23. #ifndef  HASH_FILO_H
  24. #define  HASH_FILO_H
  25.  
  26. #ifdef __GNUC__
  27. #pragma interface            /* gcc class implementation */
  28. #endif
  29.  
  30. class hash_filo_element
  31. {
  32.   hash_filo_element *next_used,*prev_used;
  33.  public:
  34.   hash_filo_element() {}
  35.   friend class hash_filo;
  36. };
  37.  
  38.  
  39. class hash_filo
  40. {
  41.   const uint size, key_offset, key_length;
  42.   const hash_get_key get_key;
  43.   void (*free_element)(void*);
  44.   bool init;
  45.  
  46.   hash_filo_element *first_link,*last_link;
  47. public:
  48.   pthread_mutex_t lock;
  49.   HASH cache;
  50.  
  51.   hash_filo(uint size_arg, uint key_offset_arg , uint key_length_arg,
  52.         hash_get_key get_key_arg,void (*free_element_arg)(void*))
  53.     :size(size_arg), key_offset(key_offset_arg), key_length(key_length_arg),
  54.     get_key(get_key_arg), free_element(free_element_arg),init(0)
  55.   {
  56.     bzero((char*) &cache,sizeof(cache));
  57.   }
  58.  
  59.   ~hash_filo()
  60.   {
  61.     if (init)
  62.     {
  63.       if (cache.array.buffer)    /* Avoid problems with thread library */
  64.     (void) hash_free(&cache);
  65.       pthread_mutex_destroy(&lock);
  66.     }
  67.   }
  68.   void clear(bool locked=0)
  69.   {
  70.     if (!init)
  71.     {
  72.       init=1;
  73.       (void) pthread_mutex_init(&lock,NULL);
  74.     }
  75.     if (!locked)
  76.       (void) pthread_mutex_lock(&lock);
  77.     (void) hash_free(&cache);
  78.     (void) hash_init(&cache,size,key_offset, key_length, get_key, free_element,
  79.              0);
  80.     if (!locked)
  81.       (void) pthread_mutex_unlock(&lock);
  82.     first_link=last_link=0;
  83.   }
  84.  
  85.   hash_filo_element *search(gptr key,uint length)
  86.   {
  87.     hash_filo_element *entry=(hash_filo_element*)
  88.       hash_search(&cache,(byte*) key,length);
  89.     if (entry)
  90.     {                        // Found; link it first
  91.       if (entry != first_link)
  92.       {                        // Relink used-chain
  93.     if (entry == last_link)
  94.       last_link=entry->prev_used;
  95.     else
  96.     {
  97.       entry->next_used->prev_used = entry->prev_used;
  98.       entry->prev_used->next_used = entry->next_used;
  99.     }
  100.     if ((entry->next_used= first_link))
  101.       first_link->prev_used=entry;
  102.     first_link=entry;
  103.       }
  104.     }
  105.     return entry;
  106.   }
  107.  
  108.   my_bool add(hash_filo_element *entry)
  109.   {
  110.     if (cache.records == size)
  111.     {
  112.       hash_filo_element *tmp=last_link;
  113.       last_link=last_link->prev_used;
  114.       hash_delete(&cache,(byte*) tmp);
  115.     }
  116.     if (hash_insert(&cache,(byte*) entry))
  117.     {
  118.       if (free_element)
  119.     (*free_element)(entry);        // This should never happen
  120.       return 1;
  121.     }
  122.     if ((entry->next_used=first_link))
  123.       first_link->prev_used=entry;
  124.     else
  125.       last_link=entry;
  126.     first_link=entry;
  127.     return 0;
  128.   }
  129. };
  130.  
  131. #endif
  132.