diff options
Diffstat (limited to 'usr.sbin/nscd/cacheplcs.c')
-rw-r--r-- | usr.sbin/nscd/cacheplcs.c | 590 |
1 files changed, 0 insertions, 590 deletions
diff --git a/usr.sbin/nscd/cacheplcs.c b/usr.sbin/nscd/cacheplcs.c deleted file mode 100644 index 37cf765..0000000 --- a/usr.sbin/nscd/cacheplcs.c +++ /dev/null @@ -1,590 +0,0 @@ -/*- - * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/time.h> - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include "cacheplcs.h" -#include "debug.h" - -static void cache_fifo_policy_update_item(struct cache_policy_ *, - struct cache_policy_item_ *); -static void cache_lfu_policy_add_item(struct cache_policy_ *, - struct cache_policy_item_ *); -static struct cache_policy_item_ * cache_lfu_policy_create_item(void); -static void cache_lfu_policy_destroy_item(struct cache_policy_item_ *); -static struct cache_policy_item_ *cache_lfu_policy_get_first_item( - struct cache_policy_ *); -static struct cache_policy_item_ *cache_lfu_policy_get_last_item( - struct cache_policy_ *); -static struct cache_policy_item_ *cache_lfu_policy_get_next_item( - struct cache_policy_ *, struct cache_policy_item_ *); -static struct cache_policy_item_ *cache_lfu_policy_get_prev_item( - struct cache_policy_ *, struct cache_policy_item_ *); -static void cache_lfu_policy_remove_item(struct cache_policy_ *, - struct cache_policy_item_ *); -static void cache_lfu_policy_update_item(struct cache_policy_ *, - struct cache_policy_item_ *); -static void cache_lru_policy_update_item(struct cache_policy_ *, - struct cache_policy_item_ *); -static void cache_queue_policy_add_item(struct cache_policy_ *, - struct cache_policy_item_ *); -static struct cache_policy_item_ * cache_queue_policy_create_item(void); -static void cache_queue_policy_destroy_item(struct cache_policy_item_ *); -static struct cache_policy_item_ *cache_queue_policy_get_first_item( - struct cache_policy_ *); -static struct cache_policy_item_ *cache_queue_policy_get_last_item( - struct cache_policy_ *); -static struct cache_policy_item_ *cache_queue_policy_get_next_item( - struct cache_policy_ *, struct cache_policy_item_ *); -static struct cache_policy_item_ *cache_queue_policy_get_prev_item( - struct cache_policy_ *, struct cache_policy_item_ *); -static void cache_queue_policy_remove_item(struct cache_policy_ *, - struct cache_policy_item_ *); -static void destroy_cache_queue_policy(struct cache_queue_policy_ *); -static struct cache_queue_policy_ *init_cache_queue_policy(void); - -/* - * All cache_queue_policy_XXX functions below will be used to fill - * the cache_queue_policy structure. They implement the most functionality of - * LRU and FIFO policies. LRU and FIFO policies are actually the - * cache_queue_policy_ with cache_update_item function changed. - */ -static struct cache_policy_item_ * -cache_queue_policy_create_item(void) -{ - struct cache_queue_policy_item_ *retval; - - TRACE_IN(cache_queue_policy_create_item); - retval = calloc(1, - sizeof(*retval)); - assert(retval != NULL); - - TRACE_OUT(cache_queue_policy_create_item); - return ((struct cache_policy_item_ *)retval); -} - -static void -cache_queue_policy_destroy_item(struct cache_policy_item_ *item) -{ - - TRACE_IN(cache_queue_policy_destroy_item); - assert(item != NULL); - free(item); - TRACE_OUT(cache_queue_policy_destroy_item); -} - -static void -cache_queue_policy_add_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_queue_policy_ *queue_policy; - struct cache_queue_policy_item_ *queue_item; - - TRACE_IN(cache_queue_policy_add_item); - queue_policy = (struct cache_queue_policy_ *)policy; - queue_item = (struct cache_queue_policy_item_ *)item; - TAILQ_INSERT_TAIL(&queue_policy->head, queue_item, entries); - TRACE_OUT(cache_queue_policy_add_item); -} - -static void -cache_queue_policy_remove_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_queue_policy_ *queue_policy; - struct cache_queue_policy_item_ *queue_item; - - TRACE_IN(cache_queue_policy_remove_item); - queue_policy = (struct cache_queue_policy_ *)policy; - queue_item = (struct cache_queue_policy_item_ *)item; - TAILQ_REMOVE(&queue_policy->head, queue_item, entries); - TRACE_OUT(cache_queue_policy_remove_item); -} - -static struct cache_policy_item_ * -cache_queue_policy_get_first_item(struct cache_policy_ *policy) -{ - struct cache_queue_policy_ *queue_policy; - - TRACE_IN(cache_queue_policy_get_first_item); - queue_policy = (struct cache_queue_policy_ *)policy; - TRACE_OUT(cache_queue_policy_get_first_item); - return ((struct cache_policy_item_ *)TAILQ_FIRST(&queue_policy->head)); -} - -static struct cache_policy_item_ * -cache_queue_policy_get_last_item(struct cache_policy_ *policy) -{ - struct cache_queue_policy_ *queue_policy; - - TRACE_IN(cache_queue_policy_get_last_item); - queue_policy = (struct cache_queue_policy_ *)policy; - TRACE_OUT(cache_queue_policy_get_last_item); - return ((struct cache_policy_item_ *)TAILQ_LAST(&queue_policy->head, - cache_queue_policy_head_)); -} - -static struct cache_policy_item_ * -cache_queue_policy_get_next_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_queue_policy_ *queue_policy; - struct cache_queue_policy_item_ *queue_item; - - TRACE_IN(cache_queue_policy_get_next_item); - queue_policy = (struct cache_queue_policy_ *)policy; - queue_item = (struct cache_queue_policy_item_ *)item; - - TRACE_OUT(cache_queue_policy_get_next_item); - return ((struct cache_policy_item_ *)TAILQ_NEXT(queue_item, entries)); -} - -static struct cache_policy_item_ * -cache_queue_policy_get_prev_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_queue_policy_ *queue_policy; - struct cache_queue_policy_item_ *queue_item; - - TRACE_IN(cache_queue_policy_get_prev_item); - queue_policy = (struct cache_queue_policy_ *)policy; - queue_item = (struct cache_queue_policy_item_ *)item; - - TRACE_OUT(cache_queue_policy_get_prev_item); - return ((struct cache_policy_item_ *)TAILQ_PREV(queue_item, - cache_queue_policy_head_, entries)); -} - -/* - * Initializes cache_queue_policy_ by filling the structure with the functions - * pointers, defined above - */ -static struct cache_queue_policy_ * -init_cache_queue_policy(void) -{ - struct cache_queue_policy_ *retval; - - TRACE_IN(init_cache_queue_policy); - retval = calloc(1, - sizeof(*retval)); - assert(retval != NULL); - - retval->parent_data.create_item_func = cache_queue_policy_create_item; - retval->parent_data.destroy_item_func = cache_queue_policy_destroy_item; - - retval->parent_data.add_item_func = cache_queue_policy_add_item; - retval->parent_data.remove_item_func = cache_queue_policy_remove_item; - - retval->parent_data.get_first_item_func = - cache_queue_policy_get_first_item; - retval->parent_data.get_last_item_func = - cache_queue_policy_get_last_item; - retval->parent_data.get_next_item_func = - cache_queue_policy_get_next_item; - retval->parent_data.get_prev_item_func = - cache_queue_policy_get_prev_item; - - TAILQ_INIT(&retval->head); - TRACE_OUT(init_cache_queue_policy); - return (retval); -} - -static void -destroy_cache_queue_policy(struct cache_queue_policy_ *queue_policy) -{ - struct cache_queue_policy_item_ *queue_item; - - TRACE_IN(destroy_cache_queue_policy); - while (!TAILQ_EMPTY(&queue_policy->head)) { - queue_item = TAILQ_FIRST(&queue_policy->head); - TAILQ_REMOVE(&queue_policy->head, queue_item, entries); - cache_queue_policy_destroy_item( - (struct cache_policy_item_ *)queue_item); - } - free(queue_policy); - TRACE_OUT(destroy_cache_queue_policy); -} - -/* - * Makes cache_queue_policy_ behave like FIFO policy - we don't do anything, - * when the cache element is updated. So it always stays in its initial - * position in the queue - that is exactly the FIFO functionality. - */ -static void -cache_fifo_policy_update_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - - TRACE_IN(cache_fifo_policy_update_item); - /* policy and item arguments are ignored */ - TRACE_OUT(cache_fifo_policy_update_item); -} - -struct cache_policy_ * -init_cache_fifo_policy(void) -{ - struct cache_queue_policy_ *retval; - - TRACE_IN(init_cache_fifo_policy); - retval = init_cache_queue_policy(); - retval->parent_data.update_item_func = cache_fifo_policy_update_item; - - TRACE_OUT(init_cache_fifo_policy); - return ((struct cache_policy_ *)retval); -} - -void -destroy_cache_fifo_policy(struct cache_policy_ *policy) -{ - struct cache_queue_policy_ *queue_policy; - - TRACE_IN(destroy_cache_fifo_policy); - queue_policy = (struct cache_queue_policy_ *)policy; - destroy_cache_queue_policy(queue_policy); - TRACE_OUT(destroy_cache_fifo_policy); -} - -/* - * Makes cache_queue_policy_ behave like LRU policy. On each update, cache - * element is moved to the end of the queue - so it would be deleted in last - * turn. That is exactly the LRU policy functionality. - */ -static void -cache_lru_policy_update_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_queue_policy_ *queue_policy; - struct cache_queue_policy_item_ *queue_item; - - TRACE_IN(cache_lru_policy_update_item); - queue_policy = (struct cache_queue_policy_ *)policy; - queue_item = (struct cache_queue_policy_item_ *)item; - - TAILQ_REMOVE(&queue_policy->head, queue_item, entries); - TAILQ_INSERT_TAIL(&queue_policy->head, queue_item, entries); - TRACE_OUT(cache_lru_policy_update_item); -} - -struct cache_policy_ * -init_cache_lru_policy(void) -{ - struct cache_queue_policy_ *retval; - - TRACE_IN(init_cache_lru_policy); - retval = init_cache_queue_policy(); - retval->parent_data.update_item_func = cache_lru_policy_update_item; - - TRACE_OUT(init_cache_lru_policy); - return ((struct cache_policy_ *)retval); -} - -void -destroy_cache_lru_policy(struct cache_policy_ *policy) -{ - struct cache_queue_policy_ *queue_policy; - - TRACE_IN(destroy_cache_lru_policy); - queue_policy = (struct cache_queue_policy_ *)policy; - destroy_cache_queue_policy(queue_policy); - TRACE_OUT(destroy_cache_lru_policy); -} - -/* - * LFU (least frequently used) policy implementation differs much from the - * LRU and FIFO (both based on cache_queue_policy_). Almost all cache_policy_ - * functions are implemented specifically for this policy. The idea of this - * policy is to represent frequency (real number) as the integer number and - * use it as the index in the array. Each array's element is - * the list of elements. For example, if we have the 100-elements - * array for this policy, the elements with frequency 0.1 (calls per-second) - * would be in 10th element of the array. - */ -static struct cache_policy_item_ * -cache_lfu_policy_create_item(void) -{ - struct cache_lfu_policy_item_ *retval; - - TRACE_IN(cache_lfu_policy_create_item); - retval = calloc(1, - sizeof(*retval)); - assert(retval != NULL); - - TRACE_OUT(cache_lfu_policy_create_item); - return ((struct cache_policy_item_ *)retval); -} - -static void -cache_lfu_policy_destroy_item(struct cache_policy_item_ *item) -{ - - TRACE_IN(cache_lfu_policy_destroy_item); - assert(item != NULL); - free(item); - TRACE_OUT(cache_lfu_policy_destroy_item); -} - -/* - * When placed in the LFU policy queue for the first time, the maximum - * frequency is assigned to the element - */ -static void -cache_lfu_policy_add_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_lfu_policy_ *lfu_policy; - struct cache_lfu_policy_item_ *lfu_item; - - TRACE_IN(cache_lfu_policy_add_item); - lfu_policy = (struct cache_lfu_policy_ *)policy; - lfu_item = (struct cache_lfu_policy_item_ *)item; - - lfu_item->frequency = CACHELIB_MAX_FREQUENCY - 1; - TAILQ_INSERT_HEAD(&(lfu_policy->groups[CACHELIB_MAX_FREQUENCY - 1]), - lfu_item, entries); - TRACE_OUT(cache_lfu_policy_add_item); -} - -/* - * On each update the frequency of the element is recalculated and, if it - * changed, the element would be moved to the another place in the array. - */ -static void -cache_lfu_policy_update_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_lfu_policy_ *lfu_policy; - struct cache_lfu_policy_item_ *lfu_item; - int index; - - TRACE_IN(cache_lfu_policy_update_item); - lfu_policy = (struct cache_lfu_policy_ *)policy; - lfu_item = (struct cache_lfu_policy_item_ *)item; - - /* - * We calculate the square of the request_count to avoid grouping of - * all elements at the start of the array (for example, if array size is - * 100 and most of its elements has frequency below the 0.01, they - * all would be grouped in the first array's position). Other - * techniques should be used here later to ensure, that elements are - * equally distributed in the array and not grouped in its beginning. - */ - if (lfu_item->parent_data.last_request_time.tv_sec != - lfu_item->parent_data.creation_time.tv_sec) { - index = ((double)lfu_item->parent_data.request_count * - (double)lfu_item->parent_data.request_count / - (lfu_item->parent_data.last_request_time.tv_sec - - lfu_item->parent_data.creation_time.tv_sec + 1)) * - CACHELIB_MAX_FREQUENCY; - if (index >= CACHELIB_MAX_FREQUENCY) - index = CACHELIB_MAX_FREQUENCY - 1; - } else - index = CACHELIB_MAX_FREQUENCY - 1; - - TAILQ_REMOVE(&(lfu_policy->groups[lfu_item->frequency]), lfu_item, - entries); - lfu_item->frequency = index; - TAILQ_INSERT_HEAD(&(lfu_policy->groups[index]), lfu_item, entries); - - TRACE_OUT(cache_lfu_policy_update_item); -} - -static void -cache_lfu_policy_remove_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_lfu_policy_ *lfu_policy; - struct cache_lfu_policy_item_ *lfu_item; - - TRACE_IN(cache_lfu_policy_remove_item); - lfu_policy = (struct cache_lfu_policy_ *)policy; - lfu_item = (struct cache_lfu_policy_item_ *)item; - - TAILQ_REMOVE(&(lfu_policy->groups[lfu_item->frequency]), lfu_item, - entries); - TRACE_OUT(cache_lfu_policy_remove_item); -} - -static struct cache_policy_item_ * -cache_lfu_policy_get_first_item(struct cache_policy_ *policy) -{ - struct cache_lfu_policy_ *lfu_policy; - struct cache_lfu_policy_item_ *lfu_item; - int i; - - TRACE_IN(cache_lfu_policy_get_first_item); - lfu_item = NULL; - lfu_policy = (struct cache_lfu_policy_ *)policy; - for (i = 0; i < CACHELIB_MAX_FREQUENCY; ++i) - if (!TAILQ_EMPTY(&(lfu_policy->groups[i]))) { - lfu_item = TAILQ_FIRST(&(lfu_policy->groups[i])); - break; - } - - TRACE_OUT(cache_lfu_policy_get_first_item); - return ((struct cache_policy_item_ *)lfu_item); -} - -static struct cache_policy_item_ * -cache_lfu_policy_get_last_item(struct cache_policy_ *policy) -{ - struct cache_lfu_policy_ *lfu_policy; - struct cache_lfu_policy_item_ *lfu_item; - int i; - - TRACE_IN(cache_lfu_policy_get_last_item); - lfu_item = NULL; - lfu_policy = (struct cache_lfu_policy_ *)policy; - for (i = CACHELIB_MAX_FREQUENCY - 1; i >= 0; --i) - if (!TAILQ_EMPTY(&(lfu_policy->groups[i]))) { - lfu_item = TAILQ_LAST(&(lfu_policy->groups[i]), - cache_lfu_policy_group_); - break; - } - - TRACE_OUT(cache_lfu_policy_get_last_item); - return ((struct cache_policy_item_ *)lfu_item); -} - -static struct cache_policy_item_ * -cache_lfu_policy_get_next_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_lfu_policy_ *lfu_policy; - struct cache_lfu_policy_item_ *lfu_item; - int i; - - TRACE_IN(cache_lfu_policy_get_next_item); - lfu_policy = (struct cache_lfu_policy_ *)policy; - lfu_item = TAILQ_NEXT((struct cache_lfu_policy_item_ *)item, entries); - if (lfu_item == NULL) - { - for (i = ((struct cache_lfu_policy_item_ *)item)->frequency + 1; - i < CACHELIB_MAX_FREQUENCY; ++i) { - if (!TAILQ_EMPTY(&(lfu_policy->groups[i]))) { - lfu_item = TAILQ_FIRST(&(lfu_policy->groups[i])); - break; - } - } - } - - TRACE_OUT(cache_lfu_policy_get_next_item); - return ((struct cache_policy_item_ *)lfu_item); -} - -static struct cache_policy_item_ * -cache_lfu_policy_get_prev_item(struct cache_policy_ *policy, - struct cache_policy_item_ *item) -{ - struct cache_lfu_policy_ *lfu_policy; - struct cache_lfu_policy_item_ *lfu_item; - int i; - - TRACE_IN(cache_lfu_policy_get_prev_item); - lfu_policy = (struct cache_lfu_policy_ *)policy; - lfu_item = TAILQ_PREV((struct cache_lfu_policy_item_ *)item, - cache_lfu_policy_group_, entries); - if (lfu_item == NULL) - { - for (i = ((struct cache_lfu_policy_item_ *)item)->frequency - 1; - i >= 0; --i) - if (!TAILQ_EMPTY(&(lfu_policy->groups[i]))) { - lfu_item = TAILQ_LAST(&(lfu_policy->groups[i]), - cache_lfu_policy_group_); - break; - } - } - - TRACE_OUT(cache_lfu_policy_get_prev_item); - return ((struct cache_policy_item_ *)lfu_item); -} - -/* - * Initializes the cache_policy_ structure by filling it with appropriate - * functions pointers - */ -struct cache_policy_ * -init_cache_lfu_policy(void) -{ - int i; - struct cache_lfu_policy_ *retval; - - TRACE_IN(init_cache_lfu_policy); - retval = calloc(1, - sizeof(*retval)); - assert(retval != NULL); - - retval->parent_data.create_item_func = cache_lfu_policy_create_item; - retval->parent_data.destroy_item_func = cache_lfu_policy_destroy_item; - - retval->parent_data.add_item_func = cache_lfu_policy_add_item; - retval->parent_data.update_item_func = cache_lfu_policy_update_item; - retval->parent_data.remove_item_func = cache_lfu_policy_remove_item; - - retval->parent_data.get_first_item_func = - cache_lfu_policy_get_first_item; - retval->parent_data.get_last_item_func = - cache_lfu_policy_get_last_item; - retval->parent_data.get_next_item_func = - cache_lfu_policy_get_next_item; - retval->parent_data.get_prev_item_func = - cache_lfu_policy_get_prev_item; - - for (i = 0; i < CACHELIB_MAX_FREQUENCY; ++i) - TAILQ_INIT(&(retval->groups[i])); - - TRACE_OUT(init_cache_lfu_policy); - return ((struct cache_policy_ *)retval); -} - -void -destroy_cache_lfu_policy(struct cache_policy_ *policy) -{ - int i; - struct cache_lfu_policy_ *lfu_policy; - struct cache_lfu_policy_item_ *lfu_item; - - TRACE_IN(destroy_cache_lfu_policy); - lfu_policy = (struct cache_lfu_policy_ *)policy; - for (i = 0; i < CACHELIB_MAX_FREQUENCY; ++i) { - while (!TAILQ_EMPTY(&(lfu_policy->groups[i]))) { - lfu_item = TAILQ_FIRST(&(lfu_policy->groups[i])); - TAILQ_REMOVE(&(lfu_policy->groups[i]), lfu_item, - entries); - cache_lfu_policy_destroy_item( - (struct cache_policy_item_ *)lfu_item); - } - } - free(policy); - TRACE_OUT(destroy_cache_lfu_policy); -} |