|
Atrinik Server 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00056 #include <global.h> 00057 00059 static cache_struct *cache = NULL; 00061 static size_t num_cache = 0; 00062 00065 static int cache_compare(const void *one, const void *two) 00066 { 00067 cache_struct *one_cache = (cache_struct *) one; 00068 cache_struct *two_cache = (cache_struct *) two; 00069 00070 if (one == NULL) 00071 { 00072 return -1; 00073 } 00074 else if (two == NULL) 00075 { 00076 return 1; 00077 } 00078 00079 if (one_cache->key < two_cache->key) 00080 { 00081 return -1; 00082 } 00083 else if (one_cache->key > two_cache->key) 00084 { 00085 return 1; 00086 } 00087 else 00088 { 00089 return 0; 00090 } 00091 } 00092 00097 cache_struct *cache_find(shstr *key) 00098 { 00099 cache_struct bkey; 00100 00101 /* Sanity. */ 00102 if (!cache || !num_cache || !key) 00103 { 00104 return NULL; 00105 } 00106 00107 /* Attempt to find the cache entry. */ 00108 bkey.key = key; 00109 return bsearch((void *) &bkey, cache, num_cache, sizeof(cache_struct), cache_compare); 00110 } 00111 00119 int cache_add(const char *key, void *ptr, uint32 flags) 00120 { 00121 size_t i, ii; 00122 shstr *sh_key = add_string(key); 00123 00124 /* Sanity. */ 00125 if (!ptr || cache_find(sh_key)) 00126 { 00127 return 0; 00128 } 00129 00130 /* Increase the array's size. */ 00131 cache = realloc(cache, sizeof(cache_struct) * (num_cache + 1)); 00132 00133 /* Now, insert the cache into the correct spot in the array. */ 00134 for (i = 0; i < num_cache; i++) 00135 { 00136 if (cache[i].key > sh_key) 00137 { 00138 break; 00139 } 00140 } 00141 00142 /* If this is not the special case of insertion at the last point, then shift everything. */ 00143 for (ii = num_cache; ii > i; ii--) 00144 { 00145 cache[ii] = cache[ii - 1]; 00146 /* Increase the ID, as it's getting moved upwards. */ 00147 cache[ii].id++; 00148 } 00149 00150 /* Store the values. */ 00151 cache[i].key = sh_key; 00152 cache[i].ptr = ptr; 00153 cache[i].flags = flags; 00154 cache[i].id = i; 00155 num_cache++; 00156 00157 return 1; 00158 } 00159 00164 int cache_remove(shstr *key) 00165 { 00166 cache_struct *entry = cache_find(key); 00167 size_t i; 00168 00169 if (!entry) 00170 { 00171 return 0; 00172 } 00173 00174 /* The entry wants global events, so send one about it being removed. */ 00175 if (entry->flags & CACHE_FLAG_GEVENT) 00176 { 00177 trigger_global_event(GEVENT_CACHE_REMOVED, entry->ptr, (uint32 *) &entry->flags); 00178 } 00179 00180 /* Does it want to be freed automatically? */ 00181 if (entry->flags & CACHE_FLAG_AUTOFREE) 00182 { 00183 free(entry->ptr); 00184 } 00185 00186 /* Shift the entries. */ 00187 for (i = entry->id + 1; i < num_cache; i++) 00188 { 00189 cache[i - 1] = cache[i]; 00190 /* Moving downwards, decrease ID. */ 00191 cache[i - 1].id--; 00192 } 00193 00194 /* Decrease the array's size. */ 00195 cache = realloc(cache, sizeof(cache_struct) * (num_cache - 1)); 00196 num_cache--; 00197 00198 return 1; 00199 } 00200 00203 void cache_remove_all() 00204 { 00205 /* Keep removing until there's nothing left. */ 00206 while (num_cache) 00207 { 00208 cache_remove(cache[0].key); 00209 } 00210 } 00211 00215 void cache_remove_by_flags(uint32 flags) 00216 { 00217 size_t i; 00218 00219 /* Search for matching entries, and remove them. */ 00220 for (i = 0; i < num_cache; i++) 00221 { 00222 if (cache[i].flags & flags) 00223 { 00224 cache_remove(cache[i].key); 00225 i--; 00226 } 00227 } 00228 }
1.7.4