hash_filo.h
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:3k
源码类别:

MySQL数据库

开发平台:

Visual C++

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