00001 /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 /* 00019 ** A class for static sized hash tables where old entries are deleted in 00020 ** first-in-last-out to usage. 00021 */ 00022 00023 #ifndef HASH_FILO_H 00024 #define HASH_FILO_H 00025 00026 #ifdef USE_PRAGMA_INTERFACE 00027 #pragma interface /* gcc class interface */ 00028 #endif 00029 00030 class hash_filo_element 00031 { 00032 hash_filo_element *next_used,*prev_used; 00033 public: 00034 hash_filo_element() {} 00035 friend class hash_filo; 00036 }; 00037 00038 00039 class hash_filo 00040 { 00041 const uint size, key_offset, key_length; 00042 const hash_get_key get_key; 00043 hash_free_key free_element; 00044 bool init; 00045 CHARSET_INFO *hash_charset; 00046 00047 hash_filo_element *first_link,*last_link; 00048 public: 00049 pthread_mutex_t lock; 00050 HASH cache; 00051 00052 hash_filo(uint size_arg, uint key_offset_arg , uint key_length_arg, 00053 hash_get_key get_key_arg, hash_free_key free_element_arg, 00054 CHARSET_INFO *hash_charset_arg) 00055 :size(size_arg), key_offset(key_offset_arg), key_length(key_length_arg), 00056 get_key(get_key_arg), free_element(free_element_arg),init(0), 00057 hash_charset(hash_charset_arg) 00058 { 00059 bzero((char*) &cache,sizeof(cache)); 00060 } 00061 00062 ~hash_filo() 00063 { 00064 if (init) 00065 { 00066 if (cache.array.buffer) /* Avoid problems with thread library */ 00067 (void) hash_free(&cache); 00068 pthread_mutex_destroy(&lock); 00069 } 00070 } 00071 void clear(bool locked=0) 00072 { 00073 if (!init) 00074 { 00075 init=1; 00076 (void) pthread_mutex_init(&lock,MY_MUTEX_INIT_FAST); 00077 } 00078 if (!locked) 00079 (void) pthread_mutex_lock(&lock); 00080 (void) hash_free(&cache); 00081 (void) hash_init(&cache,hash_charset,size,key_offset, 00082 key_length, get_key, free_element,0); 00083 if (!locked) 00084 (void) pthread_mutex_unlock(&lock); 00085 first_link=last_link=0; 00086 } 00087 00088 hash_filo_element *search(gptr key,uint length) 00089 { 00090 hash_filo_element *entry=(hash_filo_element*) 00091 hash_search(&cache,(byte*) key,length); 00092 if (entry) 00093 { // Found; link it first 00094 if (entry != first_link) 00095 { // Relink used-chain 00096 if (entry == last_link) 00097 last_link=entry->prev_used; 00098 else 00099 { 00100 entry->next_used->prev_used = entry->prev_used; 00101 entry->prev_used->next_used = entry->next_used; 00102 } 00103 if ((entry->next_used= first_link)) 00104 first_link->prev_used=entry; 00105 first_link=entry; 00106 } 00107 } 00108 return entry; 00109 } 00110 00111 my_bool add(hash_filo_element *entry) 00112 { 00113 if (cache.records == size) 00114 { 00115 hash_filo_element *tmp=last_link; 00116 last_link=last_link->prev_used; 00117 hash_delete(&cache,(byte*) tmp); 00118 } 00119 if (my_hash_insert(&cache,(byte*) entry)) 00120 { 00121 if (free_element) 00122 (*free_element)(entry); // This should never happen 00123 return 1; 00124 } 00125 if ((entry->next_used=first_link)) 00126 first_link->prev_used=entry; 00127 else 00128 last_link=entry; 00129 first_link=entry; 00130 return 0; 00131 } 00132 }; 00133 00134 #endif
1.4.7

